livemark 0.21.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -101,7 +101,7 @@ Livemark is meant to look great with zero configuration and stay out of your way
101
101
 
102
102
  Full documentation lives at **[livemark.dev](https://livemark.dev)**:
103
103
 
104
- - [Markdown reference](https://livemark.dev/markdown/) — every Markdown / MDX feature with examples
104
+ - [Authoring reference](https://livemark.dev/authoring/) — every Markdown / MDX feature with examples
105
105
  - [Customization](https://livemark.dev/customization/) — every knob, with copy-pasteable snippets
106
106
  - [Changelog](https://livemark.dev/changelog/) — release notes
107
107
  - [Contributing](https://livemark.dev/contributing/) — local setup and PR flow
@@ -1,6 +1,7 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState, useCallback } from "react";
3
3
  import { Eye, Pencil, Copy, Check, ExternalLink } from "lucide-react";
4
+ const LLM_PROMPT = "Read {url}, I want to ask questions about it.";
4
5
  /** Toolbar with action buttons displayed for the article content */
5
6
  export function PageToolbar(props) {
6
7
  const [copied, setCopied] = useState(false);
@@ -16,19 +17,20 @@ export function PageToolbar(props) {
16
17
  setCopied(true);
17
18
  setTimeout(() => setCopied(false), 2000);
18
19
  }, [props.content]);
19
- const handleOpenIn = useCallback((url) => {
20
- navigator.clipboard.writeText(props.content);
21
- window.open(url, "_blank", "noopener,noreferrer");
22
- }, [props.content]);
20
+ const openIn = (base, extra) => {
21
+ const q = LLM_PROMPT.replace("{url}", window.location.href);
22
+ const params = new URLSearchParams({ ...extra, q });
23
+ window.open(`${base}?${params}`, "_blank", "noopener,noreferrer");
24
+ };
23
25
  const buttonClass = "flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors";
24
26
  return (_jsx(_Fragment, { children: _jsxs("div", { className: "mb-6 flex flex-col gap-2 text-sm", children: [
25
27
  _jsx("p", { className: "text-sm font-medium mb-1", children: "Actions" }), sourceHref ? (_jsxs("a", { href: sourceHref, target: "_blank", rel: "noopener noreferrer", className: buttonClass, children: [
26
28
  _jsx(SourceIcon, { className: "size-3.5" }), sourceLabel] })) : (_jsxs("span", { className: `${buttonClass} opacity-50 cursor-not-allowed hover:text-muted-foreground`, "aria-disabled": "true", children: [
27
- _jsx(SourceIcon, { className: "size-3.5" }), sourceLabel] })), _jsxs("button", { type: "button", onClick: handleCopy, className: buttonClass, children: [copied ? (_jsx(Check, { className: "size-3.5" })) : (_jsx(Copy, { className: "size-3.5" })), "Copy Markdown"] }), _jsxs("button", { type: "button", onClick: () => handleOpenIn("https://chatgpt.com/"), className: buttonClass, children: [
29
+ _jsx(SourceIcon, { className: "size-3.5" }), sourceLabel] })), _jsxs("button", { type: "button", onClick: handleCopy, className: buttonClass, children: [copied ? (_jsx(Check, { className: "size-3.5" })) : (_jsx(Copy, { className: "size-3.5" })), "Copy Markdown"] }), _jsxs("button", { type: "button", onClick: () => openIn("https://chatgpt.com/", { hints: "search" }), className: buttonClass, children: [
28
30
  _jsx(ExternalLink, { className: "size-3.5" }),
29
- "Open in ChatGPT"] }), _jsxs("button", { type: "button", onClick: () => handleOpenIn("https://claude.ai/"), className: buttonClass, children: [
31
+ "Open in ChatGPT"] }), _jsxs("button", { type: "button", onClick: () => openIn("https://claude.ai/new"), className: buttonClass, children: [
30
32
  _jsx(ExternalLink, { className: "size-3.5" }),
31
33
  "Open in Claude"] })
32
34
  ] }) }));
33
35
  }
34
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFnZVRvb2xiYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zb3VyY2UvY29tcG9uZW50cy9QYWdlVG9vbGJhci50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sT0FBTyxDQUFBO0FBQzdDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBRXJFLG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsV0FBVyxDQUFDLEtBSzNCO0lBQ0MsTUFBTSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDM0MsTUFBTSxVQUFVLEdBQ2QsS0FBSyxDQUFDLFNBQVM7UUFDZixDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQ1QsQ0FBQyxDQUFDLGtEQUFrRCxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQ2hFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUNoQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsWUFBWSxLQUFLLE1BQU0sQ0FBQTtJQUM1QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQTtJQUNoRSxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFBO0lBRXhDLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUU7UUFDbEMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQzVDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNmLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDMUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7SUFFbkIsTUFBTSxZQUFZLEdBQUcsV0FBVyxDQUM5QixDQUFDLEdBQVcsRUFBRSxFQUFFO1FBQ2QsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQzVDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxxQkFBcUIsQ0FBQyxDQUFBO0lBQ25ELENBQUMsRUFDRCxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FDaEIsQ0FBQTtJQUVELE1BQU0sV0FBVyxHQUNmLGlHQUFpRyxDQUFBO0lBRW5HLE9BQU8sQ0FDTCw0QkFDRSxlQUFLLFNBQVMsRUFBQyxrQ0FBa0M7Z0JBQy9DLFlBQUcsU0FBUyxFQUFDLDBCQUEwQix3QkFBWSxFQUNsRCxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQ1osYUFDRSxJQUFJLEVBQUUsVUFBVSxFQUNoQixNQUFNLEVBQUMsUUFBUSxFQUNmLEdBQUcsRUFBQyxxQkFBcUIsRUFDekIsU0FBUyxFQUFFLFdBQVc7d0JBRXRCLEtBQUMsVUFBVSxJQUFDLFNBQVMsRUFBQyxVQUFVLEdBQUcsRUFDbEMsV0FBVyxJQUNWLENBQ0wsQ0FBQyxDQUFDLENBQUMsQ0FDRixnQkFDRSxTQUFTLEVBQUUsR0FBRyxXQUFXLDREQUE0RCxtQkFDdkUsTUFBTTt3QkFFcEIsS0FBQyxVQUFVLElBQUMsU0FBUyxFQUFDLFVBQVUsR0FBRyxFQUNsQyxXQUFXLElBQ1AsQ0FDUixFQUNELGtCQUFRLElBQUksRUFBQyxRQUFRLEVBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsV0FBVyxhQUM5RCxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQ1IsS0FBQyxLQUFLLElBQUMsU0FBUyxFQUFDLFVBQVUsR0FBRyxDQUMvQixDQUFDLENBQUMsQ0FBQyxDQUNGLEtBQUMsSUFBSSxJQUFDLFNBQVMsRUFBQyxVQUFVLEdBQUcsQ0FDOUIscUJBRU0sRUFDVCxrQkFDRSxJQUFJLEVBQUMsUUFBUSxFQUNiLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQUMsc0JBQXNCLENBQUMsRUFDbkQsU0FBUyxFQUFFLFdBQVc7d0JBRXRCLEtBQUMsWUFBWSxJQUFDLFNBQVMsRUFBQyxVQUFVLEdBQUc7NkNBRTlCLEVBQ1Qsa0JBQ0UsSUFBSSxFQUFDLFFBQVEsRUFDYixPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsWUFBWSxDQUFDLG9CQUFvQixDQUFDLEVBQ2pELFNBQVMsRUFBRSxXQUFXO3dCQUV0QixLQUFDLFlBQVksSUFBQyxTQUFTLEVBQUMsVUFBVSxHQUFHOzRDQUU5QjtnQkFDTCxHQUNMLENBQ0osQ0FBQTtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB1c2VTdGF0ZSwgdXNlQ2FsbGJhY2sgfSBmcm9tIFwicmVhY3RcIlxuaW1wb3J0IHsgRXllLCBQZW5jaWwsIENvcHksIENoZWNrLCBFeHRlcm5hbExpbmsgfSBmcm9tIFwibHVjaWRlLXJlYWN0XCJcblxuLyoqIFRvb2xiYXIgd2l0aCBhY3Rpb24gYnV0dG9ucyBkaXNwbGF5ZWQgZm9yIHRoZSBhcnRpY2xlIGNvbnRlbnQgKi9cbmV4cG9ydCBmdW5jdGlvbiBQYWdlVG9vbGJhcihwcm9wczoge1xuICBmaWxlPzogc3RyaW5nXG4gIHNvdXJjZVVybD86IHN0cmluZ1xuICBzb3VyY2VBY3Rpb24/OiBcImVkaXRcIiB8IFwidmlld1wiXG4gIGNvbnRlbnQ6IHN0cmluZ1xufSkge1xuICBjb25zdCBbY29waWVkLCBzZXRDb3BpZWRdID0gdXNlU3RhdGUoZmFsc2UpXG4gIGNvbnN0IHNvdXJjZUhyZWYgPVxuICAgIHByb3BzLnNvdXJjZVVybCA/P1xuICAgIChwcm9wcy5maWxlXG4gICAgICA/IGBodHRwczovL2dpdGh1Yi5jb20vZGF0aXN0aHEvbGl2ZW1hcmsvZWRpdC9tYWluLyR7cHJvcHMuZmlsZX1gXG4gICAgICA6IHVuZGVmaW5lZClcbiAgY29uc3QgaXNWaWV3ID0gcHJvcHMuc291cmNlQWN0aW9uID09PSBcInZpZXdcIlxuICBjb25zdCBzb3VyY2VMYWJlbCA9IGlzVmlldyA/IFwiVmlldyBvbiBHaXRIdWJcIiA6IFwiRWRpdCBvbiBHaXRIdWJcIlxuICBjb25zdCBTb3VyY2VJY29uID0gaXNWaWV3ID8gRXllIDogUGVuY2lsXG5cbiAgY29uc3QgaGFuZGxlQ29weSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBuYXZpZ2F0b3IuY2xpcGJvYXJkLndyaXRlVGV4dChwcm9wcy5jb250ZW50KVxuICAgIHNldENvcGllZCh0cnVlKVxuICAgIHNldFRpbWVvdXQoKCkgPT4gc2V0Q29waWVkKGZhbHNlKSwgMjAwMClcbiAgfSwgW3Byb3BzLmNvbnRlbnRdKVxuXG4gIGNvbnN0IGhhbmRsZU9wZW5JbiA9IHVzZUNhbGxiYWNrKFxuICAgICh1cmw6IHN0cmluZykgPT4ge1xuICAgICAgbmF2aWdhdG9yLmNsaXBib2FyZC53cml0ZVRleHQocHJvcHMuY29udGVudClcbiAgICAgIHdpbmRvdy5vcGVuKHVybCwgXCJfYmxhbmtcIiwgXCJub29wZW5lcixub3JlZmVycmVyXCIpXG4gICAgfSxcbiAgICBbcHJvcHMuY29udGVudF0sXG4gIClcblxuICBjb25zdCBidXR0b25DbGFzcyA9XG4gICAgXCJmbGV4IGl0ZW1zLWNlbnRlciBnYXAtMS41IHRleHQtc20gdGV4dC1tdXRlZC1mb3JlZ3JvdW5kIGhvdmVyOnRleHQtZm9yZWdyb3VuZCB0cmFuc2l0aW9uLWNvbG9yc1wiXG5cbiAgcmV0dXJuIChcbiAgICA8PlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJtYi02IGZsZXggZmxleC1jb2wgZ2FwLTIgdGV4dC1zbVwiPlxuICAgICAgICA8cCBjbGFzc05hbWU9XCJ0ZXh0LXNtIGZvbnQtbWVkaXVtIG1iLTFcIj5BY3Rpb25zPC9wPlxuICAgICAgICB7c291cmNlSHJlZiA/IChcbiAgICAgICAgICA8YVxuICAgICAgICAgICAgaHJlZj17c291cmNlSHJlZn1cbiAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICByZWw9XCJub29wZW5lciBub3JlZmVycmVyXCJcbiAgICAgICAgICAgIGNsYXNzTmFtZT17YnV0dG9uQ2xhc3N9XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPFNvdXJjZUljb24gY2xhc3NOYW1lPVwic2l6ZS0zLjVcIiAvPlxuICAgICAgICAgICAge3NvdXJjZUxhYmVsfVxuICAgICAgICAgIDwvYT5cbiAgICAgICAgKSA6IChcbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgY2xhc3NOYW1lPXtgJHtidXR0b25DbGFzc30gb3BhY2l0eS01MCBjdXJzb3Itbm90LWFsbG93ZWQgaG92ZXI6dGV4dC1tdXRlZC1mb3JlZ3JvdW5kYH1cbiAgICAgICAgICAgIGFyaWEtZGlzYWJsZWQ9XCJ0cnVlXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8U291cmNlSWNvbiBjbGFzc05hbWU9XCJzaXplLTMuNVwiIC8+XG4gICAgICAgICAgICB7c291cmNlTGFiZWx9XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICApfVxuICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBvbkNsaWNrPXtoYW5kbGVDb3B5fSBjbGFzc05hbWU9e2J1dHRvbkNsYXNzfT5cbiAgICAgICAgICB7Y29waWVkID8gKFxuICAgICAgICAgICAgPENoZWNrIGNsYXNzTmFtZT1cInNpemUtMy41XCIgLz5cbiAgICAgICAgICApIDogKFxuICAgICAgICAgICAgPENvcHkgY2xhc3NOYW1lPVwic2l6ZS0zLjVcIiAvPlxuICAgICAgICAgICl9XG4gICAgICAgICAgQ29weSBNYXJrZG93blxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIG9uQ2xpY2s9eygpID0+IGhhbmRsZU9wZW5JbihcImh0dHBzOi8vY2hhdGdwdC5jb20vXCIpfVxuICAgICAgICAgIGNsYXNzTmFtZT17YnV0dG9uQ2xhc3N9XG4gICAgICAgID5cbiAgICAgICAgICA8RXh0ZXJuYWxMaW5rIGNsYXNzTmFtZT1cInNpemUtMy41XCIgLz5cbiAgICAgICAgICBPcGVuIGluIENoYXRHUFRcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBoYW5kbGVPcGVuSW4oXCJodHRwczovL2NsYXVkZS5haS9cIil9XG4gICAgICAgICAgY2xhc3NOYW1lPXtidXR0b25DbGFzc31cbiAgICAgICAgPlxuICAgICAgICAgIDxFeHRlcm5hbExpbmsgY2xhc3NOYW1lPVwic2l6ZS0zLjVcIiAvPlxuICAgICAgICAgIE9wZW4gaW4gQ2xhdWRlXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC8+XG4gIClcbn1cbiJdfQ==
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFnZVRvb2xiYXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zb3VyY2UvY29tcG9uZW50cy9QYWdlVG9vbGJhci50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLE1BQU0sT0FBTyxDQUFBO0FBQzdDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBRXJFLE1BQU0sVUFBVSxHQUFHLCtDQUErQyxDQUFBO0FBRWxFLG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsV0FBVyxDQUFDLEtBSzNCO0lBQ0MsTUFBTSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDM0MsTUFBTSxVQUFVLEdBQ2QsS0FBSyxDQUFDLFNBQVM7UUFDZixDQUFDLEtBQUssQ0FBQyxJQUFJO1lBQ1QsQ0FBQyxDQUFDLGtEQUFrRCxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQ2hFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUNoQixNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsWUFBWSxLQUFLLE1BQU0sQ0FBQTtJQUM1QyxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQTtJQUNoRSxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFBO0lBRXhDLE1BQU0sVUFBVSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUU7UUFDbEMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQzVDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUNmLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDMUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7SUFFbkIsTUFBTSxNQUFNLEdBQUcsQ0FBQyxJQUFZLEVBQUUsS0FBOEIsRUFBRSxFQUFFO1FBQzlELE1BQU0sQ0FBQyxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDM0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFlLENBQUMsRUFBRSxHQUFHLEtBQUssRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ25ELE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksTUFBTSxFQUFFLEVBQUUsUUFBUSxFQUFFLHFCQUFxQixDQUFDLENBQUE7SUFDbkUsQ0FBQyxDQUFBO0lBRUQsTUFBTSxXQUFXLEdBQ2YsaUdBQWlHLENBQUE7SUFFbkcsT0FBTyxDQUNMLDRCQUNFLGVBQUssU0FBUyxFQUFDLGtDQUFrQztnQkFDL0MsWUFBRyxTQUFTLEVBQUMsMEJBQTBCLHdCQUFZLEVBQ2xELFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FDWixhQUNFLElBQUksRUFBRSxVQUFVLEVBQ2hCLE1BQU0sRUFBQyxRQUFRLEVBQ2YsR0FBRyxFQUFDLHFCQUFxQixFQUN6QixTQUFTLEVBQUUsV0FBVzt3QkFFdEIsS0FBQyxVQUFVLElBQUMsU0FBUyxFQUFDLFVBQVUsR0FBRyxFQUNsQyxXQUFXLElBQ1YsQ0FDTCxDQUFDLENBQUMsQ0FBQyxDQUNGLGdCQUNFLFNBQVMsRUFBRSxHQUFHLFdBQVcsNERBQTRELG1CQUN2RSxNQUFNO3dCQUVwQixLQUFDLFVBQVUsSUFBQyxTQUFTLEVBQUMsVUFBVSxHQUFHLEVBQ2xDLFdBQVcsSUFDUCxDQUNSLEVBQ0Qsa0JBQVEsSUFBSSxFQUFDLFFBQVEsRUFBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxXQUFXLGFBQzlELE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FDUixLQUFDLEtBQUssSUFBQyxTQUFTLEVBQUMsVUFBVSxHQUFHLENBQy9CLENBQUMsQ0FBQyxDQUFDLENBQ0YsS0FBQyxJQUFJLElBQUMsU0FBUyxFQUFDLFVBQVUsR0FBRyxDQUM5QixxQkFFTSxFQUNULGtCQUNFLElBQUksRUFBQyxRQUFRLEVBQ2IsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUNsRSxTQUFTLEVBQUUsV0FBVzt3QkFFdEIsS0FBQyxZQUFZLElBQUMsU0FBUyxFQUFDLFVBQVUsR0FBRzs2Q0FFOUIsRUFDVCxrQkFDRSxJQUFJLEVBQUMsUUFBUSxFQUNiLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsdUJBQXVCLENBQUMsRUFDOUMsU0FBUyxFQUFFLFdBQVc7d0JBRXRCLEtBQUMsWUFBWSxJQUFDLFNBQVMsRUFBQyxVQUFVLEdBQUc7NENBRTlCO2dCQUNMLEdBQ0wsQ0FDSixDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHVzZVN0YXRlLCB1c2VDYWxsYmFjayB9IGZyb20gXCJyZWFjdFwiXG5pbXBvcnQgeyBFeWUsIFBlbmNpbCwgQ29weSwgQ2hlY2ssIEV4dGVybmFsTGluayB9IGZyb20gXCJsdWNpZGUtcmVhY3RcIlxuXG5jb25zdCBMTE1fUFJPTVBUID0gXCJSZWFkIHt1cmx9LCBJIHdhbnQgdG8gYXNrIHF1ZXN0aW9ucyBhYm91dCBpdC5cIlxuXG4vKiogVG9vbGJhciB3aXRoIGFjdGlvbiBidXR0b25zIGRpc3BsYXllZCBmb3IgdGhlIGFydGljbGUgY29udGVudCAqL1xuZXhwb3J0IGZ1bmN0aW9uIFBhZ2VUb29sYmFyKHByb3BzOiB7XG4gIGZpbGU/OiBzdHJpbmdcbiAgc291cmNlVXJsPzogc3RyaW5nXG4gIHNvdXJjZUFjdGlvbj86IFwiZWRpdFwiIHwgXCJ2aWV3XCJcbiAgY29udGVudDogc3RyaW5nXG59KSB7XG4gIGNvbnN0IFtjb3BpZWQsIHNldENvcGllZF0gPSB1c2VTdGF0ZShmYWxzZSlcbiAgY29uc3Qgc291cmNlSHJlZiA9XG4gICAgcHJvcHMuc291cmNlVXJsID8/XG4gICAgKHByb3BzLmZpbGVcbiAgICAgID8gYGh0dHBzOi8vZ2l0aHViLmNvbS9kYXRpc3RocS9saXZlbWFyay9lZGl0L21haW4vJHtwcm9wcy5maWxlfWBcbiAgICAgIDogdW5kZWZpbmVkKVxuICBjb25zdCBpc1ZpZXcgPSBwcm9wcy5zb3VyY2VBY3Rpb24gPT09IFwidmlld1wiXG4gIGNvbnN0IHNvdXJjZUxhYmVsID0gaXNWaWV3ID8gXCJWaWV3IG9uIEdpdEh1YlwiIDogXCJFZGl0IG9uIEdpdEh1YlwiXG4gIGNvbnN0IFNvdXJjZUljb24gPSBpc1ZpZXcgPyBFeWUgOiBQZW5jaWxcblxuICBjb25zdCBoYW5kbGVDb3B5ID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIG5hdmlnYXRvci5jbGlwYm9hcmQud3JpdGVUZXh0KHByb3BzLmNvbnRlbnQpXG4gICAgc2V0Q29waWVkKHRydWUpXG4gICAgc2V0VGltZW91dCgoKSA9PiBzZXRDb3BpZWQoZmFsc2UpLCAyMDAwKVxuICB9LCBbcHJvcHMuY29udGVudF0pXG5cbiAgY29uc3Qgb3BlbkluID0gKGJhc2U6IHN0cmluZywgZXh0cmE/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSA9PiB7XG4gICAgY29uc3QgcSA9IExMTV9QUk9NUFQucmVwbGFjZShcInt1cmx9XCIsIHdpbmRvdy5sb2NhdGlvbi5ocmVmKVxuICAgIGNvbnN0IHBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMoeyAuLi5leHRyYSwgcSB9KVxuICAgIHdpbmRvdy5vcGVuKGAke2Jhc2V9PyR7cGFyYW1zfWAsIFwiX2JsYW5rXCIsIFwibm9vcGVuZXIsbm9yZWZlcnJlclwiKVxuICB9XG5cbiAgY29uc3QgYnV0dG9uQ2xhc3MgPVxuICAgIFwiZmxleCBpdGVtcy1jZW50ZXIgZ2FwLTEuNSB0ZXh0LXNtIHRleHQtbXV0ZWQtZm9yZWdyb3VuZCBob3Zlcjp0ZXh0LWZvcmVncm91bmQgdHJhbnNpdGlvbi1jb2xvcnNcIlxuXG4gIHJldHVybiAoXG4gICAgPD5cbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwibWItNiBmbGV4IGZsZXgtY29sIGdhcC0yIHRleHQtc21cIj5cbiAgICAgICAgPHAgY2xhc3NOYW1lPVwidGV4dC1zbSBmb250LW1lZGl1bSBtYi0xXCI+QWN0aW9uczwvcD5cbiAgICAgICAge3NvdXJjZUhyZWYgPyAoXG4gICAgICAgICAgPGFcbiAgICAgICAgICAgIGhyZWY9e3NvdXJjZUhyZWZ9XG4gICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiXG4gICAgICAgICAgICBjbGFzc05hbWU9e2J1dHRvbkNsYXNzfVxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxTb3VyY2VJY29uIGNsYXNzTmFtZT1cInNpemUtMy41XCIgLz5cbiAgICAgICAgICAgIHtzb3VyY2VMYWJlbH1cbiAgICAgICAgICA8L2E+XG4gICAgICAgICkgOiAoXG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgIGNsYXNzTmFtZT17YCR7YnV0dG9uQ2xhc3N9IG9wYWNpdHktNTAgY3Vyc29yLW5vdC1hbGxvd2VkIGhvdmVyOnRleHQtbXV0ZWQtZm9yZWdyb3VuZGB9XG4gICAgICAgICAgICBhcmlhLWRpc2FibGVkPVwidHJ1ZVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPFNvdXJjZUljb24gY2xhc3NOYW1lPVwic2l6ZS0zLjVcIiAvPlxuICAgICAgICAgICAge3NvdXJjZUxhYmVsfVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgKX1cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgb25DbGljaz17aGFuZGxlQ29weX0gY2xhc3NOYW1lPXtidXR0b25DbGFzc30+XG4gICAgICAgICAge2NvcGllZCA/IChcbiAgICAgICAgICAgIDxDaGVjayBjbGFzc05hbWU9XCJzaXplLTMuNVwiIC8+XG4gICAgICAgICAgKSA6IChcbiAgICAgICAgICAgIDxDb3B5IGNsYXNzTmFtZT1cInNpemUtMy41XCIgLz5cbiAgICAgICAgICApfVxuICAgICAgICAgIENvcHkgTWFya2Rvd25cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBvcGVuSW4oXCJodHRwczovL2NoYXRncHQuY29tL1wiLCB7IGhpbnRzOiBcInNlYXJjaFwiIH0pfVxuICAgICAgICAgIGNsYXNzTmFtZT17YnV0dG9uQ2xhc3N9XG4gICAgICAgID5cbiAgICAgICAgICA8RXh0ZXJuYWxMaW5rIGNsYXNzTmFtZT1cInNpemUtMy41XCIgLz5cbiAgICAgICAgICBPcGVuIGluIENoYXRHUFRcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBvcGVuSW4oXCJodHRwczovL2NsYXVkZS5haS9uZXdcIil9XG4gICAgICAgICAgY2xhc3NOYW1lPXtidXR0b25DbGFzc31cbiAgICAgICAgPlxuICAgICAgICAgIDxFeHRlcm5hbExpbmsgY2xhc3NOYW1lPVwic2l6ZS0zLjVcIiAvPlxuICAgICAgICAgIE9wZW4gaW4gQ2xhdWRlXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC8+XG4gIClcbn1cbiJdfQ==
@@ -1,4 +1,5 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { config } from "livemark:virtual";
2
3
  import { Link, useLocation } from "@tanstack/react-router";
3
4
  import { Clock, List, Rss, Tag } from "lucide-react";
4
5
  import { currentSection, sectionFlatArticles, sortedArticles, } from "../content/article.js";
@@ -36,10 +37,9 @@ export function SidebarPosts() {
36
37
  _splat: post.path.replace(/^\/|\/$/g, ""),
37
38
  } }), children: _jsx("span", { children: post.title }) }) }, post.path));
38
39
  }) })
39
- ] }), _jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { className: "opacity-75", children: [
40
+ ] }), config.site && (_jsx(SidebarMenuItem, { children: _jsxs(SidebarMenuButton, { className: "opacity-75", render: _jsx("a", { href: `/${sectionPath}/rss.xml` }), children: [
40
41
  _jsx(Rss, { className: "size-4" }), _jsx("span", { children: "RSS Feed" })
41
- ] }) })
42
- ] }) })
42
+ ] }) }))] }) })
43
43
  ] }), tags.length > 0 && (_jsxs(SidebarGroup, { children: [
44
44
  _jsx(SidebarGroupLabel, { className: "uppercase font-mono text-xs tracking-widest", children: "Tags" }), _jsx(SidebarGroupContent, { children: _jsx(SidebarMenu, { children: tags.map(tag => {
45
45
  const tagPath = `${sectionPath}/tags/${tag}`;
@@ -50,4 +50,4 @@ export function SidebarPosts() {
50
50
  }) }) })
51
51
  ] }))] }));
52
52
  }
53
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2lkZWJhclBvc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL2NvbXBvbmVudHMvU2lkZWJhclBvc3RzLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQTtBQUMxRCxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQ3BELE9BQU8sRUFDTCxjQUFjLEVBQ2QsbUJBQW1CLEVBQ25CLGNBQWMsR0FDZixNQUFNLHVCQUF1QixDQUFBO0FBQzlCLE9BQU8sRUFDTCxZQUFZLEVBQ1osbUJBQW1CLEVBQ25CLGlCQUFpQixFQUNqQixXQUFXLEVBQ1gsaUJBQWlCLEVBQ2pCLGVBQWUsRUFDZixjQUFjLEVBQ2Qsb0JBQW9CLEVBQ3BCLGtCQUFrQixHQUNuQixNQUFNLHdCQUF5QixDQUFBO0FBRWhDLGtGQUFrRjtBQUNsRixNQUFNLFVBQVUsWUFBWTtJQUMxQixNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQTtJQUV6RCxNQUFNLE9BQU8sR0FBRyxjQUFjLENBQUMsSUFBSSxRQUFRLENBQUMsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDdkUsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUMzRSxNQUFNLEtBQUssR0FBRyxJQUFJO1NBQ2YsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMs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QUNNO29CQUNULEVBRWQsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FDbEIsTUFBQyxZQUFZO29CQUNYLEtBQUMsaUJBQWlCLElBQUMsU0FBUyxFQUFDLDZDQUE2QyxxQkFFdEQsRUFDcEIsS0FBQyxtQkFBbUIsY0FDbEIsS0FBQyxXQUFXLGNBQ1QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRTtnQ0FDZCxNQUFNLE9BQU8sR0FBRyxHQUFHLFdBQVcsU0FBUyxHQUFHLEVBQUUsQ0FBQTtnQ0FDNUMsTUFBTSxTQUFTLEdBQUcsVUFBVSxLQUFLLElBQUksT0FBTyxHQUFHLENBQUE7Z0NBQy9DLE9BQU8sQ0FDTCxLQUFDLGVBQWUsY0FDZCxNQUFDLGlCQUFpQixJQUNoQixRQUFRLEVBQUUsU0FBUyxFQUNuQixTQUFTLEVBQUUsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFlBQVksRUFDeEMsTUFBTSxFQUFFLEtBQUMsSUFBSSxJQUFDLEVBQUUsRUFBQyxJQUFJLEVBQUMsTUFBTSxFQUFFLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFJOzRDQUVyRCxLQUFDLEdBQUcsSUFBQyxTQUFTLEVBQUMsVUFBVSxHQUFHLEVBQzVCLHlCQUFPLEdBQUcsR0FBUTs0Q0FDQSxJQVJBLEdBQUcsQ0FTUCxDQUNuQixDQUFBOzRCQUNILENBQUMsQ0FBQyxHQUNVLEdBQ007b0JBQ1QsQ0FDaEIsSUFDQSxDQUNKLENBQUE7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTGluaywgdXNlTG9jYXRpb24gfSBmcm9tIFwiQHRhbnN0YWNrL3JlYWN0LXJvdXRlclwiXG5pbXBvcnQgeyBDbG9jaywgTGlzdCwgUnNzLCBUYWcgfSBmcm9tIFwibHVjaWRlLXJlYWN0XCJcbmltcG9ydCB7XG4gIGN1cnJlbnRTZWN0aW9uLFxuICBzZWN0aW9uRmxhdEFydGljbGVzLFxuICBzb3J0ZWRBcnRpY2xlcyxcbn0gZnJvbSBcIi4uL2NvbnRlbnQvYXJ0aWNsZS50c1wiXG5pbXBvcnQge1xuICBTaWRlYmFyR3JvdXAsXG4gIFNpZGViYXJHcm91cENvbnRlbnQsXG4gIFNpZGViYXJHcm91cExhYmVsLFxuICBTaWRlYmFyTWVudSxcbiAgU2lkZWJhck1lbnVCdXR0b24sXG4gIFNpZGViYXJNZW51SXRlbSxcbiAgU2lkZWJhck1lbnVTdWIsXG4gIFNpZGViYXJNZW51U3ViQnV0dG9uLFxuICBTaWRlYmFyTWVudVN1Ykl0ZW0sXG59IGZyb20gXCIuLi9lbGVtZW50cy9zaWRlYmFyLnRzeFwiXG5cbi8qKiBCbG9nIGJvZHkgc2xvdCBmb3IgdGhlIFNpZGViYXIgc2hlbGw6IEFsbCBQb3N0cyAvIFJlY2VudCBQb3N0cyAvIFJTUyAvIFRhZ3MgKi9cbmV4cG9ydCBmdW5jdGlvbiBTaWRlYmFyUG9zdHMoKSB7XG4gIGNvbnN0IHBhdGhuYW1lID0gdXNlTG9jYXRpb24oeyBzZWxlY3Q6IGwgPT4gbC5wYXRobmFtZSB9KVxuXG4gIGNvbnN0IHNlY3Rpb24gPSBjdXJyZW50U2VjdGlvbihgLyR7cGF0aG5hbWUucmVwbGFjZSgvXlxcL3xcXC8kL2csIFwiXCIpfS9gKVxuICBjb25zdCBmbGF0ID0gc2VjdGlvbiA/IChzZWN0aW9uRmxhdEFydGljbGVzLmdldChzZWN0aW9uLnByZWZpeCkgPz8gW10pIDogW11cbiAgY29uc3QgcG9zdHMgPSBmbGF0XG4gICAgLm1hcChwID0+IHNvcnRlZEFydGljbGVzLmZpbmQoYSA9PiBhLnBhdGggPT09IHApKVxuICAgIC5maWx0ZXIoYSA9PiBhICE9PSB1bmRlZmluZWQpXG4gIGNvbnN0IHJlY2VudFBvc3RzID0gcG9zdHMuc2xpY2UoMCwgNSlcblxuICBjb25zdCBhbGxUYWdzID0gbmV3IFNldDxzdHJpbmc+KClcbiAgZm9yIChjb25zdCBwb3N0IG9mIHBvc3RzKSB7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgcG9zdC50YWdzID8/IFtdKSB7XG4gICAgICBhbGxUYWdzLmFkZCh0YWcpXG4gICAgfVxuICB9XG4gIGNvbnN0IHRhZ3MgPSBbLi4uYWxsVGFnc10uc29ydCgpXG5cbiAgY29uc3Qgbm9ybWFsaXplZCA9IGAvJHtwYXRobmFtZS5yZXBsYWNlKC9eXFwvfFxcLyQvZywgXCJcIil9L2BcbiAgY29uc3QgaXNJbmRleCA9IHNlY3Rpb24gPyBub3JtYWxpemVkID09PSBzZWN0aW9uLnByZWZpeCA6IGZhbHNlXG4gIGNvbnN0IHNlY3Rpb25QYXRoID0gKHNlY3Rpb24/LnByZWZpeCA/PyBcIi9ibG9nL1wiKS5yZXBsYWNlKC9eXFwvfFxcLyQvZywgXCJcIilcblxuICByZXR1cm4gKFxuICAgIDw+XG4gICAgICA8U2lkZWJhckdyb3VwPlxuICAgICAgICA8U2lkZWJhckdyb3VwTGFiZWwgY2xhc3NOYW1lPVwidXBwZXJjYXNlIGZvbnQtbW9ubyB0ZXh0LXhzIHRyYWNraW5nLXdpZGVzdFwiPlxuICAgICAgICAgIFBvc3RzXG4gICAgICAgIDwvU2lkZWJhckdyb3VwTGFiZWw+XG4gICAgICAgIDxTaWRlYmFyR3JvdXBDb250ZW50PlxuICAgICAgICAgIDxTaWRlYmFyTWVudT5cbiAgICAgICAgICAgIDxTaWRlYmFyTWVudUl0ZW0+XG4gICAgICAgICAgICAgIDxTaWRlYmFyTWVudUJ1dHRvblxuICAgICAgICAgICAgICAgIGlzQWN0aXZlPXtpc0luZGV4fVxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17aXNJbmRleCA/IFwiXCIgOiBcIm9wYWNpdHktNzVcIn1cbiAgICAgICAgICAgICAgICByZW5kZXI9ezxMaW5rIHRvPVwiLyRcIiBwYXJhbXM9e3sgX3NwbGF0OiBzZWN0aW9uUGF0aCB9fSAvPn1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxMaXN0IGNsYXNzTmFtZT1cInNpemUtNFwiIC8+XG4gICAgICAgICAgICAgICAgPHNwYW4+QWxsIFBvc3RzPC9zcGFuPlxuICAgICAgICAgICAgICA8L1NpZGViYXJNZW51QnV0dG9uPlxuICAgICAgICAgICAgPC9TaWRlYmFyTWVudUl0ZW0+XG4gICAgICAgICAgICA8U2lkZWJhck1lbnVJdGVtPlxuICAgICAgICAgICAgICA8U2lkZWJhck1lbnVCdXR0b24gY2xhc3NOYW1lPVwib3BhY2l0eS03NVwiPlxuICAgICAgICAgICAgICAgIDxDbG9jayBjbGFzc05hbWU9XCJzaXplLTRcIiAvPlxuICAgICAgICAgICAgICAgIDxzcGFuPlJlY2VudCBQb3N0czwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9TaWRlYmFyTWVudUJ1dHRvbj5cbiAgICAgICAgICAgICAgPFNpZGViYXJNZW51U3ViPlxuICAgICAgICAgICAgICAgIHtyZWNlbnRQb3N0cy5tYXAocG9zdCA9PiB7XG4gICAgICAgICAgICAgICAgICBjb25zdCBhY3RpdmUgPSBub3JtYWxpemVkID09PSBwb3N0LnBhdGhcbiAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxTaWRlYmFyTWVudVN1Ykl0ZW0ga2V5PXtwb3N0LnBhdGh9PlxuICAgICAgICAgICAgICAgICAgICAgIDxTaWRlYmFyTWVudVN1YkJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgaXNBY3RpdmU9e2FjdGl2ZX1cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17YWN0aXZlID8gXCJcIiA6IFwib3BhY2l0eS03NVwifVxuICAgICAgICAgICAgICAgICAgICAgICAgcmVuZGVyPXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPExpbmtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0bz1cIi8kXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJhbXM9e3tcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9zcGxhdDogcG9zdC5wYXRoLnJlcGxhY2UoL15cXC98XFwvJC9nLCBcIlwiKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPntwb3N0LnRpdGxlfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L1NpZGViYXJNZW51U3ViQnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICA8L1NpZGViYXJNZW51U3ViSXRlbT5cbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgPC9TaWRlYmFyTWVudVN1Yj5cbiAgICAgICAgICAgIDwvU2lkZWJhck1lbnVJdGVtPlxuICAgICAgICAgICAgPFNpZGViYXJNZW51SXRlbT5cbiAgICAgICAgICAgICAgPFNpZGViYXJNZW51QnV0dG9uIGNsYXNzTmFtZT1cIm9wYWNpdHktNzVcIj5cbiAgICAgICAgICAgICAgICA8UnNzIGNsYXNzTmFtZT1cInNpemUtNFwiIC8+XG4gICAgICAgICAgICAgICAgPHNwYW4+UlNTIEZlZWQ8L3NwYW4+XG4gICAgICAgICAgICAgIDwvU2lkZWJhck1lbnVCdXR0b24+XG4gICAgICAgICAgICA8L1NpZGViYXJNZW51SXRlbT5cbiAgICAgICAgICA8L1NpZGViYXJNZW51PlxuICAgICAgICA8L1NpZGViYXJHcm91cENvbnRlbnQ+XG4gICAgICA8L1NpZGViYXJHcm91cD5cblxuICAgICAge3RhZ3MubGVuZ3RoID4gMCAmJiAoXG4gICAgICAgIDxTaWRlYmFyR3JvdXA+XG4gICAgICAgICAgPFNpZGViYXJHcm91cExhYmVsIGNsYXNzTmFtZT1cInVwcGVyY2FzZSBmb250LW1vbm8gdGV4dC14cyB0cmFja2luZy13aWRlc3RcIj5cbiAgICAgICAgICAgIFRhZ3NcbiAgICAgICAgICA8L1NpZGViYXJHcm91cExhYmVsPlxuICAgICAgICAgIDxTaWRlYmFyR3JvdXBDb250ZW50PlxuICAgICAgICAgICAgPFNpZGViYXJNZW51PlxuICAgICAgICAgICAgICB7dGFncy5tYXAodGFnID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0YWdQYXRoID0gYCR7c2VjdGlvblBhdGh9L3RhZ3MvJHt0YWd9YFxuICAgICAgICAgICAgICAgIGNvbnN0IHRhZ0FjdGl2ZSA9IG5vcm1hbGl6ZWQgPT09IGAvJHt0YWdQYXRofS9gXG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgIDxTaWRlYmFyTWVudUl0ZW0ga2V5PXt0YWd9PlxuICAgICAgICAgICAgICAgICAgICA8U2lkZWJhck1lbnVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZT17dGFnQWN0aXZlfVxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17dGFnQWN0aXZlID8gXCJcIiA6IFwib3BhY2l0eS03NVwifVxuICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcj17PExpbmsgdG89XCIvJFwiIHBhcmFtcz17eyBfc3BsYXQ6IHRhZ1BhdGggfX0gLz59XG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8VGFnIGNsYXNzTmFtZT1cInNpemUtMy41XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57dGFnfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9TaWRlYmFyTWVudUJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDwvU2lkZWJhck1lbnVJdGVtPlxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICA8L1NpZGViYXJNZW51PlxuICAgICAgICAgIDwvU2lkZWJhckdyb3VwQ29udGVudD5cbiAgICAgICAgPC9TaWRlYmFyR3JvdXA+XG4gICAgICApfVxuICAgIDwvPlxuICApXG59XG4iXX0=
53
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU2lkZWJhclBvc3RzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL2NvbXBvbmVudHMvU2lkZWJhclBvc3RzLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBQ3pDLE9BQU8sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDMUQsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUNwRCxPQUFPLEVBQ0wsY0FBYyxFQUNkLG1CQUFtQixFQUNuQixjQUFjLEdBQ2YsTUFBTSx1QkFBdUIsQ0FBQTtBQUM5QixPQUFPLEVBQ0wsWUFBWSxFQUNaLG1CQUFtQixFQUNuQixpQkFBaUIsRUFDakIsV0FBVyxFQUNYLGlCQUFpQixFQUNqQixlQUFlLEVBQ2YsY0FBYyxFQUNkLG9CQUFvQixFQUNwQixrQkFBa0IsR0FDbkIsTUFBTSx3QkFBeUIsQ0FBQTtBQUVoQyxrRkFBa0Y7QUFDbEYsTUFBTSxVQUFVLFlBQVk7SUFDMUIsTUFBTSxRQUFRLEdBQUcsV0FBVyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7SUFFekQsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLElBQUksUUFBUSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQ3ZFLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7SUFDM0UsTUFBTSxLQUFLLEdBQUcsSUFBSTtTQUNmLEdBQUcsQ0FBQyxDQUFDLENB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QixNQUFNLEVBQUUsWUFBRyxJQUFJLEVBQUUsSUFBSSxXQUFXLFVBQVUsR0FBSTs0Q0FFOUMsS0FBQyxHQUFHLElBQUMsU0FBUyxFQUFDLFFBQVEsR0FBRyxFQUMxQixzQ0FBcUI7NENBQ0gsR0FDSixDQUNuQixJQUNXLEdBQ007b0JBQ1QsRUFFZCxJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxDQUNsQixNQUFDLFlBQVk7b0JBQ1gsS0FBQyxpQkFBaUIsSUFBQyxTQUFTLEVBQUMsNkNBQTZDLHFCQUV0RCxFQUNwQixLQUFDLG1CQUFtQixjQUNsQixLQUFDLFdBQVcsY0FDVCxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dDQUNkLE1BQU0sT0FBTyxHQUFHLEdBQUcsV0FBVyxTQUFTLEdBQUcsRUFBRSxDQUFBO2dDQUM1QyxNQUFNLFNBQVMsR0FBRyxVQUFVLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQTtnQ0FDL0MsT0FBTyxDQUNMLEtBQUMsZUFBZSxjQUNkLE1BQUMsaUJBQWlCLElBQ2hCLFFBQVEsRUFBRSxTQUFTLEVBQ25CLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsWUFBWSxFQUN4QyxNQUFNLEVBQUUsS0FBQyxJQUFJLElBQUMsRUFBRSxFQUFDLElBQUksRUFBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUk7NENBRXJELEtBQUMsR0FBRyxJQUFDLFNBQVMsRUFBQyxVQUFVLEdBQUcsRUFDNUIseUJBQU8sR0FBRyxHQUFROzRDQUNBLElBUkEsR0FBRyxDQVNQLENBQ25CLENBQUE7NEJBQ0gsQ0FBQyxDQUFDLEdBQ1UsR0FDTTtvQkFDVCxDQUNoQixJQUNBLENBQ0osQ0FBQTtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjb25maWcgfSBmcm9tIFwibGl2ZW1hcms6dmlydHVhbFwiXG5pbXBvcnQgeyBMaW5rLCB1c2VMb2NhdGlvbiB9IGZyb20gXCJAdGFuc3RhY2svcmVhY3Qtcm91dGVyXCJcbmltcG9ydCB7IENsb2NrLCBMaXN0LCBSc3MsIFRhZyB9IGZyb20gXCJsdWNpZGUtcmVhY3RcIlxuaW1wb3J0IHtcbiAgY3VycmVudFNlY3Rpb24sXG4gIHNlY3Rpb25GbGF0QXJ0aWNsZXMsXG4gIHNvcnRlZEFydGljbGVzLFxufSBmcm9tIFwiLi4vY29udGVudC9hcnRpY2xlLnRzXCJcbmltcG9ydCB7XG4gIFNpZGViYXJHcm91cCxcbiAgU2lkZWJhckdyb3VwQ29udGVudCxcbiAgU2lkZWJhckdyb3VwTGFiZWwsXG4gIFNpZGViYXJNZW51LFxuICBTaWRlYmFyTWVudUJ1dHRvbixcbiAgU2lkZWJhck1lbnVJdGVtLFxuICBTaWRlYmFyTWVudVN1YixcbiAgU2lkZWJhck1lbnVTdWJCdXR0b24sXG4gIFNpZGViYXJNZW51U3ViSXRlbSxcbn0gZnJvbSBcIi4uL2VsZW1lbnRzL3NpZGViYXIudHN4XCJcblxuLyoqIEJsb2cgYm9keSBzbG90IGZvciB0aGUgU2lkZWJhciBzaGVsbDogQWxsIFBvc3RzIC8gUmVjZW50IFBvc3RzIC8gUlNTIC8gVGFncyAqL1xuZXhwb3J0IGZ1bmN0aW9uIFNpZGViYXJQb3N0cygpIHtcbiAgY29uc3QgcGF0aG5hbWUgPSB1c2VMb2NhdGlvbih7IHNlbGVjdDogbCA9PiBsLnBhdGhuYW1lIH0pXG5cbiAgY29uc3Qgc2VjdGlvbiA9IGN1cnJlbnRTZWN0aW9uKGAvJHtwYXRobmFtZS5yZXBsYWNlKC9eXFwvfFxcLyQvZywgXCJcIil9L2ApXG4gIGNvbnN0IGZsYXQgPSBzZWN0aW9uID8gKHNlY3Rpb25GbGF0QXJ0aWNsZXMuZ2V0KHNlY3Rpb24ucHJlZml4KSA/PyBbXSkgOiBbXVxuICBjb25zdCBwb3N0cyA9IGZsYXRcbiAgICAubWFwKHAgPT4gc29ydGVkQXJ0aWNsZXMuZmluZChhID0+IGEucGF0aCA9PT0gcCkpXG4gICAgLmZpbHRlcihhID0+IGEgIT09IHVuZGVmaW5lZClcbiAgY29uc3QgcmVjZW50UG9zdHMgPSBwb3N0cy5zbGljZSgwLCA1KVxuXG4gIGNvbnN0IGFsbFRhZ3MgPSBuZXcgU2V0PHN0cmluZz4oKVxuICBmb3IgKGNvbnN0IHBvc3Qgb2YgcG9zdHMpIHtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBwb3N0LnRhZ3MgPz8gW10pIHtcbiAgICAgIGFsbFRhZ3MuYWRkKHRhZylcbiAgICB9XG4gIH1cbiAgY29uc3QgdGFncyA9IFsuLi5hbGxUYWdzXS5zb3J0KClcblxuICBjb25zdCBub3JtYWxpemVkID0gYC8ke3BhdGhuYW1lLnJlcGxhY2UoL15cXC98XFwvJC9nLCBcIlwiKX0vYFxuICBjb25zdCBpc0luZGV4ID0gc2VjdGlvbiA/IG5vcm1hbGl6ZWQgPT09IHNlY3Rpb24ucHJlZml4IDogZmFsc2VcbiAgY29uc3Qgc2VjdGlvblBhdGggPSAoc2VjdGlvbj8ucHJlZml4ID8/IFwiL2Jsb2cvXCIpLnJlcGxhY2UoL15cXC98XFwvJC9nLCBcIlwiKVxuXG4gIHJldHVybiAoXG4gICAgPD5cbiAgICAgIDxTaWRlYmFyR3JvdXA+XG4gICAgICAgIDxTaWRlYmFyR3JvdXBMYWJlbCBjbGFzc05hbWU9XCJ1cHBlcmNhc2UgZm9udC1tb25vIHRleHQteHMgdHJhY2tpbmctd2lkZXN0XCI+XG4gICAgICAgICAgUG9zdHNcbiAgICAgICAgPC9TaWRlYmFyR3JvdXBMYWJlbD5cbiAgICAgICAgPFNpZGViYXJHcm91cENvbnRlbnQ+XG4gICAgICAgICAgPFNpZGViYXJNZW51PlxuICAgICAgICAgICAgPFNpZGViYXJNZW51SXRlbT5cbiAgICAgICAgICAgICAgPFNpZGViYXJNZW51QnV0dG9uXG4gICAgICAgICAgICAgICAgaXNBY3RpdmU9e2lzSW5kZXh9XG4gICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtpc0luZGV4ID8gXCJcIiA6IFwib3BhY2l0eS03NVwifVxuICAgICAgICAgICAgICAgIHJlbmRlcj17PExpbmsgdG89XCIvJFwiIHBhcmFtcz17eyBfc3BsYXQ6IHNlY3Rpb25QYXRoIH19IC8+fVxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPExpc3QgY2xhc3NOYW1lPVwic2l6ZS00XCIgLz5cbiAgICAgICAgICAgICAgICA8c3Bhbj5BbGwgUG9zdHM8L3NwYW4+XG4gICAgICAgICAgICAgIDwvU2lkZWJhck1lbnVCdXR0b24+XG4gICAgICAgICAgICA8L1NpZGViYXJNZW51SXRlbT5cbiAgICAgICAgICAgIDxTaWRlYmFyTWVudUl0ZW0+XG4gICAgICAgICAgICAgIDxTaWRlYmFyTWVudUJ1dHRvbiBjbGFzc05hbWU9XCJvcGFjaXR5LTc1XCI+XG4gICAgICAgICAgICAgICAgPENsb2NrIGNsYXNzTmFtZT1cInNpemUtNFwiIC8+XG4gICAgICAgICAgICAgICAgPHNwYW4+UmVjZW50IFBvc3RzPC9zcGFuPlxuICAgICAgICAgICAgICA8L1NpZGViYXJNZW51QnV0dG9uPlxuICAgICAgICAgICAgICA8U2lkZWJhck1lbnVTdWI+XG4gICAgICAgICAgICAgICAge3JlY2VudFBvc3RzLm1hcChwb3N0ID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGFjdGl2ZSA9IG5vcm1hbGl6ZWQgPT09IHBvc3QucGF0aFxuICAgICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgICAgPFNpZGViYXJNZW51U3ViSXRlbSBrZXk9e3Bvc3QucGF0aH0+XG4gICAgICAgICAgICAgICAgICAgICAgPFNpZGViYXJNZW51U3ViQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZT17YWN0aXZlfVxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXthY3RpdmUgPyBcIlwiIDogXCJvcGFjaXR5LTc1XCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICByZW5kZXI9e1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8TGlua1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvPVwiLyRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcz17e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3NwbGF0OiBwb3N0LnBhdGgucmVwbGFjZSgvXlxcL3xcXC8kL2csIFwiXCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3Bvc3QudGl0bGV9PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwvU2lkZWJhck1lbnVTdWJCdXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvU2lkZWJhck1lbnVTdWJJdGVtPlxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIH0pfVxuICAgICAgICAgICAgICA8L1NpZGViYXJNZW51U3ViPlxuICAgICAgICAgICAgPC9TaWRlYmFyTWVudUl0ZW0+XG4gICAgICAgICAgICB7Y29uZmlnLnNpdGUgJiYgKFxuICAgICAgICAgICAgICA8U2lkZWJhck1lbnVJdGVtPlxuICAgICAgICAgICAgICAgIDxTaWRlYmFyTWVudUJ1dHRvblxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwib3BhY2l0eS03NVwiXG4gICAgICAgICAgICAgICAgICByZW5kZXI9ezxhIGhyZWY9e2AvJHtzZWN0aW9uUGF0aH0vcnNzLnhtbGB9IC8+fVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxSc3MgY2xhc3NOYW1lPVwic2l6ZS00XCIgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPlJTUyBGZWVkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvU2lkZWJhck1lbnVCdXR0b24+XG4gICAgICAgICAgICAgIDwvU2lkZWJhck1lbnVJdGVtPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICA8L1NpZGViYXJNZW51PlxuICAgICAgICA8L1NpZGViYXJHcm91cENvbnRlbnQ+XG4gICAgICA8L1NpZGViYXJHcm91cD5cblxuICAgICAge3RhZ3MubGVuZ3RoID4gMCAmJiAoXG4gICAgICAgIDxTaWRlYmFyR3JvdXA+XG4gICAgICAgICAgPFNpZGViYXJHcm91cExhYmVsIGNsYXNzTmFtZT1cInVwcGVyY2FzZSBmb250LW1vbm8gdGV4dC14cyB0cmFja2luZy13aWRlc3RcIj5cbiAgICAgICAgICAgIFRhZ3NcbiAgICAgICAgICA8L1NpZGViYXJHcm91cExhYmVsPlxuICAgICAgICAgIDxTaWRlYmFyR3JvdXBDb250ZW50PlxuICAgICAgICAgICAgPFNpZGViYXJNZW51PlxuICAgICAgICAgICAgICB7dGFncy5tYXAodGFnID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCB0YWdQYXRoID0gYCR7c2VjdGlvblBhdGh9L3RhZ3MvJHt0YWd9YFxuICAgICAgICAgICAgICAgIGNvbnN0IHRhZ0FjdGl2ZSA9IG5vcm1hbGl6ZWQgPT09IGAvJHt0YWdQYXRofS9gXG4gICAgICAgICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgICAgICAgIDxTaWRlYmFyTWVudUl0ZW0ga2V5PXt0YWd9PlxuICAgICAgICAgICAgICAgICAgICA8U2lkZWJhck1lbnVCdXR0b25cbiAgICAgICAgICAgICAgICAgICAgICBpc0FjdGl2ZT17dGFnQWN0aXZlfVxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17dGFnQWN0aXZlID8gXCJcIiA6IFwib3BhY2l0eS03NVwifVxuICAgICAgICAgICAgICAgICAgICAgIHJlbmRlcj17PExpbmsgdG89XCIvJFwiIHBhcmFtcz17eyBfc3BsYXQ6IHRhZ1BhdGggfX0gLz59XG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8VGFnIGNsYXNzTmFtZT1cInNpemUtMy41XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57dGFnfTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPC9TaWRlYmFyTWVudUJ1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDwvU2lkZWJhck1lbnVJdGVtPlxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICA8L1NpZGViYXJNZW51PlxuICAgICAgICAgIDwvU2lkZWJhckdyb3VwQ29udGVudD5cbiAgICAgICAgPC9TaWRlYmFyR3JvdXA+XG4gICAgICApfVxuICAgIDwvPlxuICApXG59XG4iXX0=
@@ -0,0 +1,21 @@
1
+ export interface RssItem {
2
+ title: string;
3
+ link: string;
4
+ guid: string;
5
+ description?: string;
6
+ pubDate?: string;
7
+ author?: string | string[];
8
+ categories?: string[];
9
+ }
10
+ export interface RssFeed {
11
+ title: string;
12
+ description: string;
13
+ link: string;
14
+ feedLink: string;
15
+ items: RssItem[];
16
+ }
17
+ /** Render an RSS 2.0 channel as a serialized XML document. Pure — all I/O,
18
+ * URL composition, and item-count limits live in the caller. `pubDate` is
19
+ * accepted as an ISO string (article frontmatter shape) and converted to
20
+ * RFC 822 here, which is what readers like NetNewsWire and Feedly parse. */
21
+ export declare function renderRssFeed(feed: RssFeed): string;
@@ -0,0 +1,56 @@
1
+ /** Render an RSS 2.0 channel as a serialized XML document. Pure — all I/O,
2
+ * URL composition, and item-count limits live in the caller. `pubDate` is
3
+ * accepted as an ISO string (article frontmatter shape) and converted to
4
+ * RFC 822 here, which is what readers like NetNewsWire and Feedly parse. */
5
+ export function renderRssFeed(feed) {
6
+ const lines = [];
7
+ lines.push('<?xml version="1.0" encoding="UTF-8"?>');
8
+ lines.push('<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">');
9
+ lines.push(" <channel>");
10
+ lines.push(` <title>${escapeXml(feed.title)}</title>`);
11
+ lines.push(` <link>${escapeXml(feed.link)}</link>`);
12
+ lines.push(` <description>${escapeXml(feed.description)}</description>`);
13
+ lines.push(` <atom:link href="${escapeXml(feed.feedLink)}" rel="self" type="application/rss+xml" />`);
14
+ for (const item of feed.items) {
15
+ lines.push(" <item>");
16
+ lines.push(` <title>${escapeXml(item.title)}</title>`);
17
+ lines.push(` <link>${escapeXml(item.link)}</link>`);
18
+ lines.push(` <guid isPermaLink="true">${escapeXml(item.guid)}</guid>`);
19
+ if (item.description) {
20
+ lines.push(` <description>${escapeXml(item.description)}</description>`);
21
+ }
22
+ if (item.pubDate) {
23
+ lines.push(` <pubDate>${escapeXml(toRfc822(item.pubDate))}</pubDate>`);
24
+ }
25
+ if (item.author) {
26
+ const author = Array.isArray(item.author)
27
+ ? item.author.join(", ")
28
+ : item.author;
29
+ lines.push(` <author>${escapeXml(author)}</author>`);
30
+ }
31
+ if (item.categories) {
32
+ for (const category of item.categories) {
33
+ lines.push(` <category>${escapeXml(category)}</category>`);
34
+ }
35
+ }
36
+ lines.push(" </item>");
37
+ }
38
+ lines.push(" </channel>");
39
+ lines.push("</rss>");
40
+ return `${lines.join("\n")}\n`;
41
+ }
42
+ function escapeXml(value) {
43
+ return value
44
+ .replace(/&/g, "&amp;")
45
+ .replace(/</g, "&lt;")
46
+ .replace(/>/g, "&gt;")
47
+ .replace(/"/g, "&quot;")
48
+ .replace(/'/g, "&apos;");
49
+ }
50
+ function toRfc822(iso) {
51
+ const date = new Date(iso);
52
+ if (Number.isNaN(date.getTime()))
53
+ return iso;
54
+ return date.toUTCString();
55
+ }
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnNzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL2hlbHBlcnMvcnNzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQWtCQTs7OzZFQUc2RTtBQUM3RSxNQUFNLFVBQVUsYUFBYSxDQUFDLElBQWE7SUFDekMsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFBO0lBQzFCLEtBQUssQ0FBQyxJQUFJLENBQUMsd0NBQXdDLENBQUMsQ0FBQTtJQUNwRCxLQUFLLENBQUMsSUFBSSxDQUFDLDhEQUE4RCxDQUFDLENBQUE7SUFDMUUsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUN6QixLQUFLLENBQUMsSUFBSSxDQUFDLGNBQWMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLENBQUE7SUFDekQsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQ3RELEtBQUssQ0FBQyxJQUFJLENBQUMsb0JBQW9CLFNBQVMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLENBQUE7SUFDM0UsS0FBSyxDQUFDLElBQUksQ0FDUix3QkFBd0IsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsNENBQTRDLENBQzdGLENBQUE7SUFDRCxLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM5QixLQUFLLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQ3hCLEtBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQzNELEtBQUssQ0FBQyxJQUFJLENBQUMsZUFBZSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUN4RCxLQUFLLENBQUMsSUFBSSxDQUFDLGtDQUFrQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUMzRSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixLQUFLLENBQUMsSUFBSSxDQUNSLHNCQUFzQixTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FDbEUsQ0FBQTtRQUNILENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixLQUFLLENBQUMsSUFBSSxDQUNSLGtCQUFrQixTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxZQUFZLENBQ2hFLENBQUE7UUFDSCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDaEIsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO2dCQUN2QyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUN4QixDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQTtZQUNmLEtBQUssQ0FBQyxJQUFJLENBQUMsaUJBQWlCLFNBQVMsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUE7UUFDM0QsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BCLEtBQUssTUFBTSxRQUFRLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUN2QyxLQUFLLENBQUMsSUFBSSxDQUFDLG1CQUFtQixTQUFTLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFBO1lBQ2pFLENBQUM7UUFDSCxDQUFDO1FBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUMzQixDQUFDO0lBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUMxQixLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ3BCLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUE7QUFDaEMsQ0FBQztBQUVELFNBQVMsU0FBUyxDQUFDLEtBQWE7SUFDOUIsT0FBTyxLQUFLO1NBQ1QsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUM7U0FDdEIsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7U0FDckIsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7U0FDckIsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUM7U0FDdkIsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQTtBQUM1QixDQUFDO0FBRUQsU0FBUyxRQUFRLENBQUMsR0FBVztJQUMzQixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUMxQixJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQUUsT0FBTyxHQUFHLENBQUE7SUFDNUMsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUE7QUFDM0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgUnNzSXRlbSB7XG4gIHRpdGxlOiBzdHJpbmdcbiAgbGluazogc3RyaW5nXG4gIGd1aWQ6IHN0cmluZ1xuICBkZXNjcmlwdGlvbj86IHN0cmluZ1xuICBwdWJEYXRlPzogc3RyaW5nXG4gIGF1dGhvcj86IHN0cmluZyB8IHN0cmluZ1tdXG4gIGNhdGVnb3JpZXM/OiBzdHJpbmdbXVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJzc0ZlZWQge1xuICB0aXRsZTogc3RyaW5nXG4gIGRlc2NyaXB0aW9uOiBzdHJpbmdcbiAgbGluazogc3RyaW5nXG4gIGZlZWRMaW5rOiBzdHJpbmdcbiAgaXRlbXM6IFJzc0l0ZW1bXVxufVxuXG4vKiogUmVuZGVyIGFuIFJTUyAyLjAgY2hhbm5lbCBhcyBhIHNlcmlhbGl6ZWQgWE1MIGRvY3VtZW50LiBQdXJlIOKAlCBhbGwgSS9PLFxuICogIFVSTCBjb21wb3NpdGlvbiwgYW5kIGl0ZW0tY291bnQgbGltaXRzIGxpdmUgaW4gdGhlIGNhbGxlci4gYHB1YkRhdGVgIGlzXG4gKiAgYWNjZXB0ZWQgYXMgYW4gSVNPIHN0cmluZyAoYXJ0aWNsZSBmcm9udG1hdHRlciBzaGFwZSkgYW5kIGNvbnZlcnRlZCB0b1xuICogIFJGQyA4MjIgaGVyZSwgd2hpY2ggaXMgd2hhdCByZWFkZXJzIGxpa2UgTmV0TmV3c1dpcmUgYW5kIEZlZWRseSBwYXJzZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJSc3NGZWVkKGZlZWQ6IFJzc0ZlZWQpIHtcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW11cbiAgbGluZXMucHVzaCgnPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+JylcbiAgbGluZXMucHVzaCgnPHJzcyB2ZXJzaW9uPVwiMi4wXCIgeG1sbnM6YXRvbT1cImh0dHA6Ly93d3cudzMub3JnLzIwMDUvQXRvbVwiPicpXG4gIGxpbmVzLnB1c2goXCIgIDxjaGFubmVsPlwiKVxuICBsaW5lcy5wdXNoKGAgICAgPHRpdGxlPiR7ZXNjYXBlWG1sKGZlZWQudGl0bGUpfTwvdGl0bGU+YClcbiAgbGluZXMucHVzaChgICAgIDxsaW5rPiR7ZXNjYXBlWG1sKGZlZWQubGluayl9PC9saW5rPmApXG4gIGxpbmVzLnB1c2goYCAgICA8ZGVzY3JpcHRpb24+JHtlc2NhcGVYbWwoZmVlZC5kZXNjcmlwdGlvbil9PC9kZXNjcmlwdGlvbj5gKVxuICBsaW5lcy5wdXNoKFxuICAgIGAgICAgPGF0b206bGluayBocmVmPVwiJHtlc2NhcGVYbWwoZmVlZC5mZWVkTGluayl9XCIgcmVsPVwic2VsZlwiIHR5cGU9XCJhcHBsaWNhdGlvbi9yc3MreG1sXCIgLz5gLFxuICApXG4gIGZvciAoY29uc3QgaXRlbSBvZiBmZWVkLml0ZW1zKSB7XG4gICAgbGluZXMucHVzaChcIiAgICA8aXRlbT5cIilcbiAgICBsaW5lcy5wdXNoKGAgICAgICA8dGl0bGU+JHtlc2NhcGVYbWwoaXRlbS50aXRsZSl9PC90aXRsZT5gKVxuICAgIGxpbmVzLnB1c2goYCAgICAgIDxsaW5rPiR7ZXNjYXBlWG1sKGl0ZW0ubGluayl9PC9saW5rPmApXG4gICAgbGluZXMucHVzaChgICAgICAgPGd1aWQgaXNQZXJtYUxpbms9XCJ0cnVlXCI+JHtlc2NhcGVYbWwoaXRlbS5ndWlkKX08L2d1aWQ+YClcbiAgICBpZiAoaXRlbS5kZXNjcmlwdGlvbikge1xuICAgICAgbGluZXMucHVzaChcbiAgICAgICAgYCAgICAgIDxkZXNjcmlwdGlvbj4ke2VzY2FwZVhtbChpdGVtLmRlc2NyaXB0aW9uKX08L2Rlc2NyaXB0aW9uPmAsXG4gICAgICApXG4gICAgfVxuICAgIGlmIChpdGVtLnB1YkRhdGUpIHtcbiAgICAgIGxpbmVzLnB1c2goXG4gICAgICAgIGAgICAgICA8cHViRGF0ZT4ke2VzY2FwZVhtbCh0b1JmYzgyMihpdGVtLnB1YkRhdGUpKX08L3B1YkRhdGU+YCxcbiAgICAgIClcbiAgICB9XG4gICAgaWYgKGl0ZW0uYXV0aG9yKSB7XG4gICAgICBjb25zdCBhdXRob3IgPSBBcnJheS5pc0FycmF5KGl0ZW0uYXV0aG9yKVxuICAgICAgICA/IGl0ZW0uYXV0aG9yLmpvaW4oXCIsIFwiKVxuICAgICAgICA6IGl0ZW0uYXV0aG9yXG4gICAgICBsaW5lcy5wdXNoKGAgICAgICA8YXV0aG9yPiR7ZXNjYXBlWG1sKGF1dGhvcil9PC9hdXRob3I+YClcbiAgICB9XG4gICAgaWYgKGl0ZW0uY2F0ZWdvcmllcykge1xuICAgICAgZm9yIChjb25zdCBjYXRlZ29yeSBvZiBpdGVtLmNhdGVnb3JpZXMpIHtcbiAgICAgICAgbGluZXMucHVzaChgICAgICAgPGNhdGVnb3J5PiR7ZXNjYXBlWG1sKGNhdGVnb3J5KX08L2NhdGVnb3J5PmApXG4gICAgICB9XG4gICAgfVxuICAgIGxpbmVzLnB1c2goXCIgICAgPC9pdGVtPlwiKVxuICB9XG4gIGxpbmVzLnB1c2goXCIgIDwvY2hhbm5lbD5cIilcbiAgbGluZXMucHVzaChcIjwvcnNzPlwiKVxuICByZXR1cm4gYCR7bGluZXMuam9pbihcIlxcblwiKX1cXG5gXG59XG5cbmZ1bmN0aW9uIGVzY2FwZVhtbCh2YWx1ZTogc3RyaW5nKSB7XG4gIHJldHVybiB2YWx1ZVxuICAgIC5yZXBsYWNlKC8mL2csIFwiJmFtcDtcIilcbiAgICAucmVwbGFjZSgvPC9nLCBcIiZsdDtcIilcbiAgICAucmVwbGFjZSgvPi9nLCBcIiZndDtcIilcbiAgICAucmVwbGFjZSgvXCIvZywgXCImcXVvdDtcIilcbiAgICAucmVwbGFjZSgvJy9nLCBcIiZhcG9zO1wiKVxufVxuXG5mdW5jdGlvbiB0b1JmYzgyMihpc286IHN0cmluZykge1xuICBjb25zdCBkYXRlID0gbmV3IERhdGUoaXNvKVxuICBpZiAoTnVtYmVyLmlzTmFOKGRhdGUuZ2V0VGltZSgpKSkgcmV0dXJuIGlzb1xuICByZXR1cm4gZGF0ZS50b1VUQ1N0cmluZygpXG59XG4iXX0=
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,123 @@
1
+ import { describe, expect, it } from "vite-plus/test";
2
+ import { renderRssFeed } from "./rss.js";
3
+ describe("renderRssFeed", () => {
4
+ it("renders a minimal channel with no items", () => {
5
+ const xml = renderRssFeed({
6
+ title: "Blog",
7
+ description: "Latest posts",
8
+ link: "https://example.com/blog/",
9
+ feedLink: "https://example.com/blog/rss.xml",
10
+ items: [],
11
+ });
12
+ expect(xml).toBe(`<?xml version="1.0" encoding="UTF-8"?>
13
+ <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
14
+ <channel>
15
+ <title>Blog</title>
16
+ <link>https://example.com/blog/</link>
17
+ <description>Latest posts</description>
18
+ <atom:link href="https://example.com/blog/rss.xml" rel="self" type="application/rss+xml" />
19
+ </channel>
20
+ </rss>
21
+ `);
22
+ });
23
+ it("renders an item with all optional fields", () => {
24
+ const xml = renderRssFeed({
25
+ title: "Blog",
26
+ description: "Latest posts",
27
+ link: "https://example.com/blog/",
28
+ feedLink: "https://example.com/blog/rss.xml",
29
+ items: [
30
+ {
31
+ title: "Hello",
32
+ link: "https://example.com/blog/hello/",
33
+ guid: "https://example.com/blog/hello/",
34
+ description: "First post",
35
+ pubDate: "2026-05-16T00:00:00Z",
36
+ author: "Jane",
37
+ categories: ["news"],
38
+ },
39
+ ],
40
+ });
41
+ expect(xml).toContain("<title>Hello</title>");
42
+ expect(xml).toContain("<link>https://example.com/blog/hello/</link>");
43
+ expect(xml).toContain('<guid isPermaLink="true">https://example.com/blog/hello/</guid>');
44
+ expect(xml).toContain("<description>First post</description>");
45
+ expect(xml).toContain("<pubDate>Sat, 16 May 2026 00:00:00 GMT</pubDate>");
46
+ expect(xml).toContain("<author>Jane</author>");
47
+ expect(xml).toContain("<category>news</category>");
48
+ });
49
+ it("joins array authors with a comma", () => {
50
+ const xml = renderRssFeed({
51
+ title: "Blog",
52
+ description: "",
53
+ link: "https://example.com/blog/",
54
+ feedLink: "https://example.com/blog/rss.xml",
55
+ items: [
56
+ {
57
+ title: "x",
58
+ link: "https://example.com/blog/x/",
59
+ guid: "https://example.com/blog/x/",
60
+ author: ["Alice", "Bob"],
61
+ },
62
+ ],
63
+ });
64
+ expect(xml).toContain("<author>Alice, Bob</author>");
65
+ });
66
+ it("emits one <category> per tag", () => {
67
+ const xml = renderRssFeed({
68
+ title: "Blog",
69
+ description: "",
70
+ link: "https://example.com/blog/",
71
+ feedLink: "https://example.com/blog/rss.xml",
72
+ items: [
73
+ {
74
+ title: "x",
75
+ link: "https://example.com/blog/x/",
76
+ guid: "https://example.com/blog/x/",
77
+ categories: ["a", "b", "c"],
78
+ },
79
+ ],
80
+ });
81
+ expect(xml).toContain("<category>a</category>");
82
+ expect(xml).toContain("<category>b</category>");
83
+ expect(xml).toContain("<category>c</category>");
84
+ });
85
+ it("escapes XML metacharacters in text content", () => {
86
+ const xml = renderRssFeed({
87
+ title: 'Title & "quoted" <tag>',
88
+ description: "A & B",
89
+ link: "https://example.com/blog/",
90
+ feedLink: "https://example.com/blog/rss.xml",
91
+ items: [
92
+ {
93
+ title: "1 < 2 & 3 > 0",
94
+ link: "https://example.com/blog/x/",
95
+ guid: "https://example.com/blog/x/",
96
+ description: "It's fine",
97
+ },
98
+ ],
99
+ });
100
+ expect(xml).toContain("<title>Title &amp; &quot;quoted&quot; &lt;tag&gt;</title>");
101
+ expect(xml).toContain("<description>A &amp; B</description>");
102
+ expect(xml).toContain("<title>1 &lt; 2 &amp; 3 &gt; 0</title>");
103
+ expect(xml).toContain("<description>It&apos;s fine</description>");
104
+ });
105
+ it("leaves an unparsable pubDate unchanged", () => {
106
+ const xml = renderRssFeed({
107
+ title: "Blog",
108
+ description: "",
109
+ link: "https://example.com/blog/",
110
+ feedLink: "https://example.com/blog/rss.xml",
111
+ items: [
112
+ {
113
+ title: "x",
114
+ link: "https://example.com/blog/x/",
115
+ guid: "https://example.com/blog/x/",
116
+ pubDate: "not-a-date",
117
+ },
118
+ ],
119
+ });
120
+ expect(xml).toContain("<pubDate>not-a-date</pubDate>");
121
+ });
122
+ });
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnNzLnVuaXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zb3VyY2UvaGVscGVycy9yc3MudW5pdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQTtBQUNyRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBRXhDLFFBQVEsQ0FBQyxlQUFlLEVBQUUsR0FBRyxFQUFFO0lBQzdCLEVBQUUsQ0FBQyx5Q0FBeUMsRUFBRSxHQUFHLEVBQUU7UUFDakQsTUFBTSxHQUFHLEdBQUcsYUFBYSxDQUFDO1lBQ3hCLEtBQUssRUFBRSxNQUFNO1lBQ2IsV0FBVyxFQUFFLGNBQWM7WUFDM0IsSUFBSSxFQUFFLDJCQUEyQjtZQUNqQyxRQUFRLEVBQUUsa0NBQWtDO1lBQzVDLEtBQUssRUFBRSxFQUFFO1NBQ1YsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FDZDs7Ozs7Ozs7O0NBU0wsQ0FDSSxDQUFBO0lBQ0gsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsMENBQTBDLEVBQUUsR0FBRyxFQUFFO1FBQ2xELE1BQU0sR0FBRyxHQUFHLGFBQWEsQ0FBQztZQUN4QixLQUFLLEVBQUUsTUFBTTtZQUNiLFdBQVcsRUFBRSxjQUFjO1lBQzNCLElBQUksRUFBRSwyQkFBMkI7WUFDakMsUUFBUSxFQUFFLGtDQUFrQztZQUM1QyxLQUFLLEVBQUU7Z0JBQ0w7b0JBQ0UsS0FBSyxFQUFFLE9BQU87b0JBQ2QsSUFBSSxFQUFFLGlDQUFpQztvQkFDdkMsSUFBSSxFQUFFLGlDQUFpQztvQkFDdkMsV0FBVyxFQUFFLFlBQVk7b0JBQ3pCLE9BQU8sRUFBRSxzQkFBc0I7b0JBQy9CLE1BQU0sRUFBRSxNQUFNO29CQUNkLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQztpQkFDckI7YUFDRjtTQUNGLENBQUMs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QyxDQUFDLENBQUE7UUFDL0QsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsQ0FBQywyQ0FBMkMsQ0FBQyxDQUFBO0lBQ3BFLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHdDQUF3QyxFQUFFLEdBQUcsRUFBRTtRQUNoRCxNQUFNLEdBQUcsR0FBRyxhQUFhLENBQUM7WUFDeEIsS0FBSyxFQUFFLE1BQU07WUFDYixXQUFXLEVBQUUsRUFBRTtZQUNmLElBQUksRUFBRSwyQkFBMkI7WUFDakMsUUFBUSxFQUFFLGtDQUFrQztZQUM1QyxLQUFLLEVBQUU7Z0JBQ0w7b0JBQ0UsS0FBSyxFQUFFLEdBQUc7b0JBQ1YsSUFBSSxFQUFFLDZCQUE2QjtvQkFDbkMsSUFBSSxFQUFFLDZCQUE2QjtvQkFDbkMsT0FBTyxFQUFFLFlBQVk7aUJBQ3RCO2FBQ0Y7U0FDRixDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLCtCQUErQixDQUFDLENBQUE7SUFDeEQsQ0FBQyxDQUFDLENBQUE7QUFDSixDQUFDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRlc2NyaWJlLCBleHBlY3QsIGl0IH0gZnJvbSBcInZpdGUtcGx1cy90ZXN0XCJcbmltcG9ydCB7IHJlbmRlclJzc0ZlZWQgfSBmcm9tIFwiLi9yc3MudHNcIlxuXG5kZXNjcmliZShcInJlbmRlclJzc0ZlZWRcIiwgKCkgPT4ge1xuICBpdChcInJlbmRlcnMgYSBtaW5pbWFsIGNoYW5uZWwgd2l0aCBubyBpdGVtc1wiLCAoKSA9PiB7XG4gICAgY29uc3QgeG1sID0gcmVuZGVyUnNzRmVlZCh7XG4gICAgICB0aXRsZTogXCJCbG9nXCIsXG4gICAgICBkZXNjcmlwdGlvbjogXCJMYXRlc3QgcG9zdHNcIixcbiAgICAgIGxpbms6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9ibG9nL1wiLFxuICAgICAgZmVlZExpbms6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9ibG9nL3Jzcy54bWxcIixcbiAgICAgIGl0ZW1zOiBbXSxcbiAgICB9KVxuICAgIGV4cGVjdCh4bWwpLnRvQmUoXG4gICAgICBgPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+XG48cnNzIHZlcnNpb249XCIyLjBcIiB4bWxuczphdG9tPVwiaHR0cDovL3d3dy53My5vcmcvMjAwNS9BdG9tXCI+XG4gIDxjaGFubmVsPlxuICAgIDx0aXRsZT5CbG9nPC90aXRsZT5cbiAgICA8bGluaz5odHRwczovL2V4YW1wbGUuY29tL2Jsb2cvPC9saW5rPlxuICAgIDxkZXNjcmlwdGlvbj5MYXRlc3QgcG9zdHM8L2Rlc2NyaXB0aW9uPlxuICAgIDxhdG9tOmxpbmsgaHJlZj1cImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9yc3MueG1sXCIgcmVsPVwic2VsZlwiIHR5cGU9XCJhcHBsaWNhdGlvbi9yc3MreG1sXCIgLz5cbiAgPC9jaGFubmVsPlxuPC9yc3M+XG5gLFxuICAgIClcbiAgfSlcblxuICBpdChcInJlbmRlcnMgYW4gaXRlbSB3aXRoIGFsbCBvcHRpb25hbCBmaWVsZHNcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHhtbCA9IHJlbmRlclJzc0ZlZWQoe1xuICAgICAgdGl0bGU6IFwiQmxvZ1wiLFxuICAgICAgZGVzY3JpcHRpb246IFwiTGF0ZXN0IHBvc3RzXCIsXG4gICAgICBsaW5rOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9cIixcbiAgICAgIGZlZWRMaW5rOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9yc3MueG1sXCIsXG4gICAgICBpdGVtczogW1xuICAgICAgICB7XG4gICAgICAgICAgdGl0bGU6IFwiSGVsbG9cIixcbiAgICAgICAgICBsaW5rOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9oZWxsby9cIixcbiAgICAgICAgICBndWlkOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9oZWxsby9cIixcbiAgICAgICAgICBkZXNjcmlwdGlvbjogXCJGaXJzdCBwb3N0XCIsXG4gICAgICAgICAgcHViRGF0ZTogXCIyMDI2LTA1LTE2VDAwOjAwOjAwWlwiLFxuICAgICAgICAgIGF1dGhvcjogXCJKYW5lXCIsXG4gICAgICAgICAgY2F0ZWdvcmllczogW1wibmV3c1wiXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSlcbiAgICBleHBlY3QoeG1sKS50b0NvbnRhaW4oXCI8dGl0bGU+SGVsbG88L3RpdGxlPlwiKVxuICAgIGV4cGVjdCh4bWwpLnRvQ29udGFpbihcIjxsaW5rPmh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9oZWxsby88L2xpbms+XCIpXG4gICAgZXhwZWN0KHhtbCkudG9Db250YWluKFxuICAgICAgJzxndWlkIGlzUGVybWFMaW5rPVwidHJ1ZVwiPmh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9oZWxsby88L2d1aWQ+JyxcbiAgICApXG4gICAgZXhwZWN0KHhtbCkudG9Db250YWluKFwiPGRlc2NyaXB0aW9uPkZpcnN0IHBvc3Q8L2Rlc2NyaXB0aW9uPlwiKVxuICAgIGV4cGVjdCh4bWwpLnRvQ29udGFpbihcIjxwdWJEYXRlPlNhdCwgMTYgTWF5IDIwMjYgMDA6MDA6MDAgR01UPC9wdWJEYXRlPlwiKVxuICAgIGV4cGVjdCh4bWwpLnRvQ29udGFpbihcIjxhdXRob3I+SmFuZTwvYXV0aG9yPlwiKVxuICAgIGV4cGVjdCh4bWwpLnRvQ29udGFpbihcIjxjYXRlZ29yeT5uZXdzPC9jYXRlZ29yeT5cIilcbiAgfSlcblxuICBpdChcImpvaW5zIGFycmF5IGF1dGhvcnMgd2l0aCBhIGNvbW1hXCIsICgpID0+IHtcbiAgICBjb25zdCB4bWwgPSByZW5kZXJSc3NGZWVkKHtcbiAgICAgIHRpdGxlOiBcIkJsb2dcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlwiLFxuICAgICAgbGluazogXCJodHRwczovL2V4YW1wbGUuY29tL2Jsb2cvXCIsXG4gICAgICBmZWVkTGluazogXCJodHRwczovL2V4YW1wbGUuY29tL2Jsb2cvcnNzLnhtbFwiLFxuICAgICAgaXRlbXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHRpdGxlOiBcInhcIixcbiAgICAgICAgICBsaW5rOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy94L1wiLFxuICAgICAgICAgIGd1aWQ6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9ibG9nL3gvXCIsXG4gICAgICAgICAgYXV0aG9yOiBbXCJBbGljZVwiLCBcIkJvYlwiXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSlcbiAgICBleHBlY3QoeG1sKS50b0NvbnRhaW4oXCI8YXV0aG9yPkFsaWNlLCBCb2I8L2F1dGhvcj5cIilcbiAgfSlcblxuICBpdChcImVtaXRzIG9uZSA8Y2F0ZWdvcnk+IHBlciB0YWdcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHhtbCA9IHJlbmRlclJzc0ZlZWQoe1xuICAgICAgdGl0bGU6IFwiQmxvZ1wiLFxuICAgICAgZGVzY3JpcHRpb246IFwiXCIsXG4gICAgICBsaW5rOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9cIixcbiAgICAgIGZlZWRMaW5rOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy9yc3MueG1sXCIsXG4gICAgICBpdGVtczogW1xuICAgICAgICB7XG4gICAgICAgICAgdGl0bGU6IFwieFwiLFxuICAgICAgICAgIGxpbms6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9ibG9nL3gvXCIsXG4gICAgICAgICAgZ3VpZDogXCJodHRwczovL2V4YW1wbGUuY29tL2Jsb2cveC9cIixcbiAgICAgICAgICBjYXRlZ29yaWVzOiBbXCJhXCIsIFwiYlwiLCBcImNcIl0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pXG4gICAgZXhwZWN0KHhtbCkudG9Db250YWluKFwiPGNhdGVnb3J5PmE8L2NhdGVnb3J5PlwiKVxuICAgIGV4cGVjdCh4bWwpLnRvQ29udGFpbihcIjxjYXRlZ29yeT5iPC9jYXRlZ29yeT5cIilcbiAgICBleHBlY3QoeG1sKS50b0NvbnRhaW4oXCI8Y2F0ZWdvcnk+YzwvY2F0ZWdvcnk+XCIpXG4gIH0pXG5cbiAgaXQoXCJlc2NhcGVzIFhNTCBtZXRhY2hhcmFjdGVycyBpbiB0ZXh0IGNvbnRlbnRcIiwgKCkgPT4ge1xuICAgIGNvbnN0IHhtbCA9IHJlbmRlclJzc0ZlZWQoe1xuICAgICAgdGl0bGU6ICdUaXRsZSAmIFwicXVvdGVkXCIgPHRhZz4nLFxuICAgICAgZGVzY3JpcHRpb246IFwiQSAmIEJcIixcbiAgICAgIGxpbms6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9ibG9nL1wiLFxuICAgICAgZmVlZExpbms6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9ibG9nL3Jzcy54bWxcIixcbiAgICAgIGl0ZW1zOiBbXG4gICAgICAgIHtcbiAgICAgICAgICB0aXRsZTogXCIxIDwgMiAmIDMgPiAwXCIsXG4gICAgICAgICAgbGluazogXCJodHRwczovL2V4YW1wbGUuY29tL2Jsb2cveC9cIixcbiAgICAgICAgICBndWlkOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy94L1wiLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkl0J3MgZmluZVwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KVxuICAgIGV4cGVjdCh4bWwpLnRvQ29udGFpbihcbiAgICAgIFwiPHRpdGxlPlRpdGxlICZhbXA7ICZxdW90O3F1b3RlZCZxdW90OyAmbHQ7dGFnJmd0OzwvdGl0bGU+XCIsXG4gICAgKVxuICAgIGV4cGVjdCh4bWwpLnRvQ29udGFpbihcIjxkZXNjcmlwdGlvbj5BICZhbXA7IEI8L2Rlc2NyaXB0aW9uPlwiKVxuICAgIGV4cGVjdCh4bWwpLnRvQ29udGFpbihcIjx0aXRsZT4xICZsdDsgMiAmYW1wOyAzICZndDsgMDwvdGl0bGU+XCIpXG4gICAgZXhwZWN0KHhtbCkudG9Db250YWluKFwiPGRlc2NyaXB0aW9uPkl0JmFwb3M7cyBmaW5lPC9kZXNjcmlwdGlvbj5cIilcbiAgfSlcblxuICBpdChcImxlYXZlcyBhbiB1bnBhcnNhYmxlIHB1YkRhdGUgdW5jaGFuZ2VkXCIsICgpID0+IHtcbiAgICBjb25zdCB4bWwgPSByZW5kZXJSc3NGZWVkKHtcbiAgICAgIHRpdGxlOiBcIkJsb2dcIixcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlwiLFxuICAgICAgbGluazogXCJodHRwczovL2V4YW1wbGUuY29tL2Jsb2cvXCIsXG4gICAgICBmZWVkTGluazogXCJodHRwczovL2V4YW1wbGUuY29tL2Jsb2cvcnNzLnhtbFwiLFxuICAgICAgaXRlbXM6IFtcbiAgICAgICAge1xuICAgICAgICAgIHRpdGxlOiBcInhcIixcbiAgICAgICAgICBsaW5rOiBcImh0dHBzOi8vZXhhbXBsZS5jb20vYmxvZy94L1wiLFxuICAgICAgICAgIGd1aWQ6IFwiaHR0cHM6Ly9leGFtcGxlLmNvbS9ibG9nL3gvXCIsXG4gICAgICAgICAgcHViRGF0ZTogXCJub3QtYS1kYXRlXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pXG4gICAgZXhwZWN0KHhtbCkudG9Db250YWluKFwiPHB1YkRhdGU+bm90LWEtZGF0ZTwvcHViRGF0ZT5cIilcbiAgfSlcbn0pXG4iXX0=
@@ -1,32 +1,38 @@
1
1
  import { Route as rootRouteImport } from './routes/__root';
2
2
  import { Route as splatRouteImport } from './routes/$';
3
+ import { Route as SectionRssDotxmlRouteImport } from './routes/$section.rss[.]xml';
3
4
  import { Route as IndexRouteImport } from './../.livemark/routes/index';
4
5
  declare const splatRoute: any;
6
+ declare const SectionRssDotxmlRoute: any;
5
7
  declare const IndexRoute: any;
6
8
  export interface FileRoutesByFullPath {
7
9
  '/': typeof IndexRoute;
8
10
  '/$': typeof splatRoute;
11
+ '/$section/rss.xml': typeof SectionRssDotxmlRoute;
9
12
  }
10
13
  export interface FileRoutesByTo {
11
14
  '/': typeof IndexRoute;
12
15
  '/$': typeof splatRoute;
16
+ '/$section/rss.xml': typeof SectionRssDotxmlRoute;
13
17
  }
14
18
  export interface FileRoutesById {
15
19
  __root__: typeof rootRouteImport;
16
20
  '/': typeof IndexRoute;
17
21
  '/$': typeof splatRoute;
22
+ '/$section/rss.xml': typeof SectionRssDotxmlRoute;
18
23
  }
19
24
  export interface FileRouteTypes {
20
25
  fileRoutesByFullPath: FileRoutesByFullPath;
21
- fullPaths: '/' | '/$';
26
+ fullPaths: '/' | '/$' | '/$section/rss.xml';
22
27
  fileRoutesByTo: FileRoutesByTo;
23
- to: '/' | '/$';
24
- id: '__root__' | '/' | '/$';
28
+ to: '/' | '/$' | '/$section/rss.xml';
29
+ id: '__root__' | '/' | '/$' | '/$section/rss.xml';
25
30
  fileRoutesById: FileRoutesById;
26
31
  }
27
32
  export interface RootRouteChildren {
28
33
  IndexRoute: typeof IndexRoute;
29
34
  splatRoute: typeof splatRoute;
35
+ SectionRssDotxmlRoute: typeof SectionRssDotxmlRoute;
30
36
  }
31
37
  declare module '@tanstack/react-router' {
32
38
  interface FileRoutesByPath {
@@ -37,6 +43,13 @@ declare module '@tanstack/react-router' {
37
43
  preLoaderRoute: typeof splatRouteImport;
38
44
  parentRoute: typeof rootRouteImport;
39
45
  };
46
+ '/$section/rss.xml': {
47
+ id: '/$section/rss.xml';
48
+ path: '/$section/rss.xml';
49
+ fullPath: '/$section/rss.xml';
50
+ preLoaderRoute: typeof SectionRssDotxmlRouteImport;
51
+ parentRoute: typeof rootRouteImport;
52
+ };
40
53
  '/': {
41
54
  id: '/';
42
55
  path: '/';
@@ -6,12 +6,18 @@
6
6
  // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
7
7
  import { Route as rootRouteImport } from './routes/__root';
8
8
  import { Route as splatRouteImport } from './routes/$';
9
+ import { Route as SectionRssDotxmlRouteImport } from './routes/$section.rss[.]xml';
9
10
  import { Route as IndexRouteImport } from './../.livemark/routes/index';
10
11
  const splatRoute = splatRouteImport.update({
11
12
  id: '/$',
12
13
  path: '/$',
13
14
  getParentRoute: () => rootRouteImport,
14
15
  });
16
+ const SectionRssDotxmlRoute = SectionRssDotxmlRouteImport.update({
17
+ id: '/$section/rss.xml',
18
+ path: '/$section/rss.xml',
19
+ getParentRoute: () => rootRouteImport,
20
+ });
15
21
  const IndexRoute = IndexRouteImport.update({
16
22
  id: '/',
17
23
  path: '/',
@@ -20,8 +26,9 @@ const IndexRoute = IndexRouteImport.update({
20
26
  const rootRouteChildren = {
21
27
  IndexRoute: IndexRoute,
22
28
  splatRoute: splatRoute,
29
+ SectionRssDotxmlRoute: SectionRssDotxmlRoute,
23
30
  };
24
31
  export const routeTree = rootRouteImport
25
32
  ._addFileChildren(rootRouteChildren)
26
33
  ._addFileTypes();
27
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVUcmVlLmdlbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9yb3V0ZVRyZWUuZ2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9CQUFvQjtBQUVwQixjQUFjO0FBRWQscUNBQXFDO0FBRXJDLDREQUE0RDtBQUM1RCwwRUFBMEU7QUFDMUUsa0lBQWtJO0FBRWxJLE9BQU8sRUFBRSxLQUFLLElBQUksZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDMUQsT0FBTyxFQUFFLEtBQUssSUFBSSxnQkFBZ0IsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUN0RCxPQUFPLEVBQUUsS0FBSyxJQUFJLGdCQUFnQixFQUFFLE1BQU0sNkJBQTZCLENBQUE7QUFFdkUsTUFBTSxVQUFVLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxDQUFDO0lBQ3pDLEVBQUUsRUFBRSxJQUFJO0lBQ1IsSUFBSSxFQUFFLElBQUk7SUFDVixjQUFjLEVBQUUsR0FBRyxFQUFFLENBQUMsZUFBZTtDQUMvQixDQUFDLENBQUE7QUFDVCxNQUFNLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7SUFDekMsRUFBRSxFQUFFLEdBQUc7SUFDUCxJQUFJLEVBQUUsR0FBRztJQUNULGNBQWMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxlQUFlO0NBQy9CLENBQUMsQ0FBQTtBQStDVCxNQUFNLGlCQUFpQixHQUFzQjtJQUMzQyxVQUFVLEVBQUUsVUFBVTtJQUN0QixVQUFVLEVBQUUsVUFBVTtDQUN2QixDQUFBO0FBQ0QsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLGVBQWU7S0FDckMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUM7S0FDbkMsYUFBYSxFQUFrQixDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgKi9cblxuLy8gQHRzLW5vY2hlY2tcblxuLy8gbm9pbnNwZWN0aW9uIEpTVW51c2VkR2xvYmFsU3ltYm9sc1xuXG4vLyBUaGlzIGZpbGUgd2FzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IFRhblN0YWNrIFJvdXRlci5cbi8vIFlvdSBzaG91bGQgTk9UIG1ha2UgYW55IGNoYW5nZXMgaW4gdGhpcyBmaWxlIGFzIGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4uXG4vLyBBZGRpdGlvbmFsbHksIHlvdSBzaG91bGQgYWxzbyBleGNsdWRlIHRoaXMgZmlsZSBmcm9tIHlvdXIgbGludGVyIGFuZC9vciBmb3JtYXR0ZXIgdG8gcHJldmVudCBpdCBmcm9tIGJlaW5nIGNoZWNrZWQgb3IgbW9kaWZpZWQuXG5cbmltcG9ydCB7IFJvdXRlIGFzIHJvb3RSb3V0ZUltcG9ydCB9IGZyb20gJy4vcm91dGVzL19fcm9vdCdcbmltcG9ydCB7IFJvdXRlIGFzIHNwbGF0Um91dGVJbXBvcnQgfSBmcm9tICcuL3JvdXRlcy8kJ1xuaW1wb3J0IHsgUm91dGUgYXMgSW5kZXhSb3V0ZUltcG9ydCB9IGZyb20gJy4vLi4vLmxpdmVtYXJrL3JvdXRlcy9pbmRleCdcblxuY29uc3Qgc3BsYXRSb3V0ZSA9IHNwbGF0Um91dGVJbXBvcnQudXBkYXRlKHtcbiAgaWQ6ICcvJCcsXG4gIHBhdGg6ICcvJCcsXG4gIGdldFBhcmVudFJvdXRlOiAoKSA9PiByb290Um91dGVJbXBvcnQsXG59IGFzIGFueSlcbmNvbnN0IEluZGV4Um91dGUgPSBJbmRleFJvdXRlSW1wb3J0LnVwZGF0ZSh7XG4gIGlkOiAnLycsXG4gIHBhdGg6ICcvJyxcbiAgZ2V0UGFyZW50Um91dGU6ICgpID0+IHJvb3RSb3V0ZUltcG9ydCxcbn0gYXMgYW55KVxuXG5leHBvcnQgaW50ZXJmYWNlIEZpbGVSb3V0ZXNCeUZ1bGxQYXRoIHtcbiAgJy8nOiB0eXBlb2YgSW5kZXhSb3V0ZVxuICAnLyQnOiB0eXBlb2Ygc3BsYXRSb3V0ZVxufVxuZXhwb3J0IGludGVyZmFjZSBGaWxlUm91dGVzQnlUbyB7XG4gICcvJzogdHlwZW9mIEluZGV4Um91dGVcbiAgJy8kJzogdHlwZW9mIHNwbGF0Um91dGVcbn1cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZVJvdXRlc0J5SWQge1xuICBfX3Jvb3RfXzogdHlwZW9mIHJvb3RSb3V0ZUltcG9ydFxuICAnLyc6IHR5cGVvZiBJbmRleFJvdXRlXG4gICcvJCc6IHR5cGVvZiBzcGxhdFJvdXRlXG59XG5leHBvcnQgaW50ZXJmYWNlIEZpbGVSb3V0ZVR5cGVzIHtcbiAgZmlsZVJvdXRlc0J5RnVsbFBhdGg6IEZpbGVSb3V0ZXNCeUZ1bGxQYXRoXG4gIGZ1bGxQYXRoczogJy8nIHwgJy8kJ1xuICBmaWxlUm91dGVzQnlUbzogRmlsZVJvdXRlc0J5VG9cbiAgdG86ICcvJyB8ICcvJCdcbiAgaWQ6ICdfX3Jvb3RfXycgfCAnLycgfCAnLyQnXG4gIGZpbGVSb3V0ZXNCeUlkOiBGaWxlUm91dGVzQnlJZFxufVxuZXhwb3J0IGludGVyZmFjZSBSb290Um91dGVDaGlsZHJlbiB7XG4gIEluZGV4Um91dGU6IHR5cGVvZiBJbmRleFJvdXRlXG4gIHNwbGF0Um91dGU6IHR5cGVvZiBzcGxhdFJvdXRlXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGFuc3RhY2svcmVhY3Qtcm91dGVyJyB7XG4gIGludGVyZmFjZSBGaWxlUm91dGVzQnlQYXRoIHtcbiAgICAnLyQnOiB7XG4gICAgICBpZDogJy8kJ1xuICAgICAgcGF0aDogJy8kJ1xuICAgICAgZnVsbFBhdGg6ICcvJCdcbiAgICAgIHByZUxvYWRlclJvdXRlOiB0eXBlb2Ygc3BsYXRSb3V0ZUltcG9ydFxuICAgICAgcGFyZW50Um91dGU6IHR5cGVvZiByb290Um91dGVJbXBvcnRcbiAgICB9XG4gICAgJy8nOiB7XG4gICAgICBpZDogJy8nXG4gICAgICBwYXRoOiAnLydcbiAgICAgIGZ1bGxQYXRoOiAnLydcbiAgICAgIHByZUxvYWRlclJvdXRlOiB0eXBlb2YgSW5kZXhSb3V0ZUltcG9ydFxuICAgICAgcGFyZW50Um91dGU6IHR5cGVvZiByb290Um91dGVJbXBvcnRcbiAgICB9XG4gIH1cbn1cblxuY29uc3Qgcm9vdFJvdXRlQ2hpbGRyZW46IFJvb3RSb3V0ZUNoaWxkcmVuID0ge1xuICBJbmRleFJvdXRlOiBJbmRleFJvdXRlLFxuICBzcGxhdFJvdXRlOiBzcGxhdFJvdXRlLFxufVxuZXhwb3J0IGNvbnN0IHJvdXRlVHJlZSA9IHJvb3RSb3V0ZUltcG9ydFxuICAuX2FkZEZpbGVDaGlsZHJlbihyb290Um91dGVDaGlsZHJlbilcbiAgLl9hZGRGaWxlVHlwZXM8RmlsZVJvdXRlVHlwZXM+KClcblxuaW1wb3J0IHR5cGUgeyBnZXRSb3V0ZXIgfSBmcm9tICcuL3JvdXRlci50c3gnXG5pbXBvcnQgdHlwZSB7IGNyZWF0ZVN0YXJ0IH0gZnJvbSAnQHRhbnN0YWNrL3JlYWN0LXN0YXJ0J1xuZGVjbGFyZSBtb2R1bGUgJ0B0YW5zdGFjay9yZWFjdC1zdGFydCcge1xuICBpbnRlcmZhY2UgUmVnaXN0ZXIge1xuICAgIHNzcjogdHJ1ZVxuICAgIHJvdXRlcjogQXdhaXRlZDxSZXR1cm5UeXBlPHR5cGVvZiBnZXRSb3V0ZXI+PlxuICB9XG59XG4iXX0=
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGVUcmVlLmdlbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NvdXJjZS9yb3V0ZVRyZWUuZ2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLG9CQUFvQjtBQUVwQixjQUFjO0FBRWQscUNBQXFDO0FBRXJDLDREQUE0RDtBQUM1RCwwRUFBMEU7QUFDMUUsa0lBQWtJO0FBRWxJLE9BQU8sRUFBRSxLQUFLLElBQUksZUFBZSxFQUFFLE1BQU0saUJBQWlCLENBQUE7QUFDMUQsT0FBTyxFQUFFLEtBQUssSUFBSSxnQkFBZ0IsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUN0RCxPQUFPLEVBQUUsS0FBSyxJQUFJLDJCQUEyQixFQUFFLE1BQU0sNkJBQTZCLENBQUE7QUFDbEYsT0FBTyxFQUFFLEtBQUssSUFBSSxnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFBO0FBRXZFLE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQztJQUN6QyxFQUFFLEVBQUUsSUFBSTtJQUNSLElBQUksRUFBRSxJQUFJO0lBQ1YsY0FBYyxFQUFFLEdBQUcsRUFBRSxDQUFDLGVBQWU7Q0FDL0IsQ0FBQyxDQUFBO0FBQ1QsTUFBTSxxQkFBcUIsR0FBRywyQkFBMkIsQ0FBQyxNQUFNLENBQUM7SUFDL0QsRUFBRSxFQUFFLG1CQUFtQjtJQUN2QixJQUFJLEVBQUUsbUJBQW1CO0lBQ3pCLGNBQWMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxlQUFlO0NBQy9CLENBQUMsQ0FBQTtBQUNULE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLE1BQU0sQ0FBQztJQUN6QyxFQUFFLEVBQUUsR0FBRztJQUNQLElBQUksRUFBRSxHQUFHO0lBQ1QsY0FBYyxFQUFFLEdBQUcsRUFBRSxDQUFDLGVBQWU7Q0FDL0IsQ0FBQyxDQUFBO0FBMERULE1BQU0saUJBQWlCLEdBQXNCO0lBQzNDLFVBQVUsRUFBRSxVQUFVO0lBQ3RCLFVBQVUsRUFBRSxVQUFVO0lBQ3RCLHFCQUFxQixFQUFFLHFCQUFxQjtDQUM3QyxDQUFBO0FBQ0QsTUFBTSxDQUFDLE1BQU0sU0FBUyxHQUFHLGVBQWU7S0FDckMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUM7S0FDbkMsYUFBYSxFQUFrQixDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgKi9cblxuLy8gQHRzLW5vY2hlY2tcblxuLy8gbm9pbnNwZWN0aW9uIEpTVW51c2VkR2xvYmFsU3ltYm9sc1xuXG4vLyBUaGlzIGZpbGUgd2FzIGF1dG9tYXRpY2FsbHkgZ2VuZXJhdGVkIGJ5IFRhblN0YWNrIFJvdXRlci5cbi8vIFlvdSBzaG91bGQgTk9UIG1ha2UgYW55IGNoYW5nZXMgaW4gdGhpcyBmaWxlIGFzIGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4uXG4vLyBBZGRpdGlvbmFsbHksIHlvdSBzaG91bGQgYWxzbyBleGNsdWRlIHRoaXMgZmlsZSBmcm9tIHlvdXIgbGludGVyIGFuZC9vciBmb3JtYXR0ZXIgdG8gcHJldmVudCBpdCBmcm9tIGJlaW5nIGNoZWNrZWQgb3IgbW9kaWZpZWQuXG5cbmltcG9ydCB7IFJvdXRlIGFzIHJvb3RSb3V0ZUltcG9ydCB9IGZyb20gJy4vcm91dGVzL19fcm9vdCdcbmltcG9ydCB7IFJvdXRlIGFzIHNwbGF0Um91dGVJbXBvcnQgfSBmcm9tICcuL3JvdXRlcy8kJ1xuaW1wb3J0IHsgUm91dGUgYXMgU2VjdGlvblJzc0RvdHhtbFJvdXRlSW1wb3J0IH0gZnJvbSAnLi9yb3V0ZXMvJHNlY3Rpb24ucnNzWy5deG1sJ1xuaW1wb3J0IHsgUm91dGUgYXMgSW5kZXhSb3V0ZUltcG9ydCB9IGZyb20gJy4vLi4vLmxpdmVtYXJrL3JvdXRlcy9pbmRleCdcblxuY29uc3Qgc3BsYXRSb3V0ZSA9IHNwbGF0Um91dGVJbXBvcnQudXBkYXRlKHtcbiAgaWQ6ICcvJCcsXG4gIHBhdGg6ICcvJCcsXG4gIGdldFBhcmVudFJvdXRlOiAoKSA9PiByb290Um91dGVJbXBvcnQsXG59IGFzIGFueSlcbmNvbnN0IFNlY3Rpb25Sc3NEb3R4bWxSb3V0ZSA9IFNlY3Rpb25Sc3NEb3R4bWxSb3V0ZUltcG9ydC51cGRhdGUoe1xuICBpZDogJy8kc2VjdGlvbi9yc3MueG1sJyxcbiAgcGF0aDogJy8kc2VjdGlvbi9yc3MueG1sJyxcbiAgZ2V0UGFyZW50Um91dGU6ICgpID0+IHJvb3RSb3V0ZUltcG9ydCxcbn0gYXMgYW55KVxuY29uc3QgSW5kZXhSb3V0ZSA9IEluZGV4Um91dGVJbXBvcnQudXBkYXRlKHtcbiAgaWQ6ICcvJyxcbiAgcGF0aDogJy8nLFxuICBnZXRQYXJlbnRSb3V0ZTogKCkgPT4gcm9vdFJvdXRlSW1wb3J0LFxufSBhcyBhbnkpXG5cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZVJvdXRlc0J5RnVsbFBhdGgge1xuICAnLyc6IHR5cGVvZiBJbmRleFJvdXRlXG4gICcvJCc6IHR5cGVvZiBzcGxhdFJvdXRlXG4gICcvJHNlY3Rpb24vcnNzLnhtbCc6IHR5cGVvZiBTZWN0aW9uUnNzRG90eG1sUm91dGVcbn1cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZVJvdXRlc0J5VG8ge1xuICAnLyc6IHR5cGVvZiBJbmRleFJvdXRlXG4gICcvJCc6IHR5cGVvZiBzcGxhdFJvdXRlXG4gICcvJHNlY3Rpb24vcnNzLnhtbCc6IHR5cGVvZiBTZWN0aW9uUnNzRG90eG1sUm91dGVcbn1cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZVJvdXRlc0J5SWQge1xuICBfX3Jvb3RfXzogdHlwZW9mIHJvb3RSb3V0ZUltcG9ydFxuICAnLyc6IHR5cGVvZiBJbmRleFJvdXRlXG4gICcvJCc6IHR5cGVvZiBzcGxhdFJvdXRlXG4gICcvJHNlY3Rpb24vcnNzLnhtbCc6IHR5cGVvZiBTZWN0aW9uUnNzRG90eG1sUm91dGVcbn1cbmV4cG9ydCBpbnRlcmZhY2UgRmlsZVJvdXRlVHlwZXMge1xuICBmaWxlUm91dGVzQnlGdWxsUGF0aDogRmlsZVJvdXRlc0J5RnVsbFBhdGhcbiAgZnVsbFBhdGhzOiAnLycgfCAnLyQnIHwgJy8kc2VjdGlvbi9yc3MueG1sJ1xuICBmaWxlUm91dGVzQnlUbzogRmlsZVJvdXRlc0J5VG9cbiAgdG86ICcvJyB8ICcvJCcgfCAnLyRzZWN0aW9uL3Jzcy54bWwnXG4gIGlkOiAnX19yb290X18nIHwgJy8nIHwgJy8kJyB8ICcvJHNlY3Rpb24vcnNzLnhtbCdcbiAgZmlsZVJvdXRlc0J5SWQ6IEZpbGVSb3V0ZXNCeUlkXG59XG5leHBvcnQgaW50ZXJmYWNlIFJvb3RSb3V0ZUNoaWxkcmVuIHtcbiAgSW5kZXhSb3V0ZTogdHlwZW9mIEluZGV4Um91dGVcbiAgc3BsYXRSb3V0ZTogdHlwZW9mIHNwbGF0Um91dGVcbiAgU2VjdGlvblJzc0RvdHhtbFJvdXRlOiB0eXBlb2YgU2VjdGlvblJzc0RvdHhtbFJvdXRlXG59XG5cbmRlY2xhcmUgbW9kdWxlICdAdGFuc3RhY2svcmVhY3Qtcm91dGVyJyB7XG4gIGludGVyZmFjZSBGaWxlUm91dGVzQnlQYXRoIHtcbiAgICAnLyQnOiB7XG4gICAgICBpZDogJy8kJ1xuICAgICAgcGF0aDogJy8kJ1xuICAgICAgZnVsbFBhdGg6ICcvJCdcbiAgICAgIHByZUxvYWRlclJvdXRlOiB0eXBlb2Ygc3BsYXRSb3V0ZUltcG9ydFxuICAgICAgcGFyZW50Um91dGU6IHR5cGVvZiByb290Um91dGVJbXBvcnRcbiAgICB9XG4gICAgJy8kc2VjdGlvbi9yc3MueG1sJzoge1xuICAgICAgaWQ6ICcvJHNlY3Rpb24vcnNzLnhtbCdcbiAgICAgIHBhdGg6ICcvJHNlY3Rpb24vcnNzLnhtbCdcbiAgICAgIGZ1bGxQYXRoOiAnLyRzZWN0aW9uL3Jzcy54bWwnXG4gICAgICBwcmVMb2FkZXJSb3V0ZTogdHlwZW9mIFNlY3Rpb25Sc3NEb3R4bWxSb3V0ZUltcG9ydFxuICAgICAgcGFyZW50Um91dGU6IHR5cGVvZiByb290Um91dGVJbXBvcnRcbiAgICB9XG4gICAgJy8nOiB7XG4gICAgICBpZDogJy8nXG4gICAgICBwYXRoOiAnLydcbiAgICAgIGZ1bGxQYXRoOiAnLydcbiAgICAgIHByZUxvYWRlclJvdXRlOiB0eXBlb2YgSW5kZXhSb3V0ZUltcG9ydFxuICAgICAgcGFyZW50Um91dGU6IHR5cGVvZiByb290Um91dGVJbXBvcnRcbiAgICB9XG4gIH1cbn1cblxuY29uc3Qgcm9vdFJvdXRlQ2hpbGRyZW46IFJvb3RSb3V0ZUNoaWxkcmVuID0ge1xuICBJbmRleFJvdXRlOiBJbmRleFJvdXRlLFxuICBzcGxhdFJvdXRlOiBzcGxhdFJvdXRlLFxuICBTZWN0aW9uUnNzRG90eG1sUm91dGU6IFNlY3Rpb25Sc3NEb3R4bWxSb3V0ZSxcbn1cbmV4cG9ydCBjb25zdCByb3V0ZVRyZWUgPSByb290Um91dGVJbXBvcnRcbiAgLl9hZGRGaWxlQ2hpbGRyZW4ocm9vdFJvdXRlQ2hpbGRyZW4pXG4gIC5fYWRkRmlsZVR5cGVzPEZpbGVSb3V0ZVR5cGVzPigpXG5cbmltcG9ydCB0eXBlIHsgZ2V0Um91dGVyIH0gZnJvbSAnLi9yb3V0ZXIudHN4J1xuaW1wb3J0IHR5cGUgeyBjcmVhdGVTdGFydCB9IGZyb20gJ0B0YW5zdGFjay9yZWFjdC1zdGFydCdcbmRlY2xhcmUgbW9kdWxlICdAdGFuc3RhY2svcmVhY3Qtc3RhcnQnIHtcbiAgaW50ZXJmYWNlIFJlZ2lzdGVyIHtcbiAgICBzc3I6IHRydWVcbiAgICByb3V0ZXI6IEF3YWl0ZWQ8UmV0dXJuVHlwZTx0eXBlb2YgZ2V0Um91dGVyPj5cbiAgfVxufVxuIl19
@@ -0,0 +1,7 @@
1
+ export declare const Route: import("@tanstack/router-core").Route<import("@tanstack/react-router").Register, any, "/$section/rss.xml", "/$section/rss.xml", "/$section/rss.xml", "/$section/rss.xml", undefined, import("@tanstack/react-router").ResolveParams<"/$section/rss.xml">, import("@tanstack/react-router").AnyContext, import("@tanstack/react-router").AnyContext, import("@tanstack/react-router").AnyContext, {}, undefined, unknown, unknown, unknown, unknown, {
2
+ GET: ({ params }: {
3
+ params: {
4
+ section: string;
5
+ };
6
+ }) => Promise<Response>;
7
+ }>;
@@ -0,0 +1,56 @@
1
+ import { config } from "livemark:virtual";
2
+ import { createFileRoute } from "@tanstack/react-router";
3
+ import { sectionFlatArticles, sortedArticles } from "../content/article.js";
4
+ import { renderRssFeed } from "../helpers/rss.js";
5
+ const FEED_ITEM_LIMIT = 20;
6
+ export const Route = createFileRoute("/$section/rss.xml")({
7
+ server: {
8
+ handlers: {
9
+ GET: async ({ params }) => {
10
+ if (!config.site) {
11
+ return new Response("RSS requires `site` in livemark.config.ts", {
12
+ status: 404,
13
+ });
14
+ }
15
+ const prefix = `/${params.section}/`;
16
+ const section = config.sections?.find(s => s.type === "blog" && s.prefix === prefix);
17
+ if (!section || section.type !== "blog") {
18
+ return new Response("Not found", { status: 404 });
19
+ }
20
+ const host = config.site.replace(/\/+$/, "");
21
+ const base = config.base ?? "";
22
+ const toAbsolute = (path) => `${host}${base}${path}`;
23
+ const paths = sectionFlatArticles.get(section.prefix) ?? [];
24
+ const items = [];
25
+ for (const path of paths) {
26
+ if (items.length >= FEED_ITEM_LIMIT)
27
+ break;
28
+ const article = sortedArticles.find(a => a.path === path);
29
+ if (!article?.date)
30
+ continue;
31
+ const link = toAbsolute(article.path);
32
+ items.push({
33
+ title: article.title,
34
+ link,
35
+ guid: link,
36
+ description: article.description,
37
+ pubDate: article.date,
38
+ author: article.author,
39
+ categories: article.tags,
40
+ });
41
+ }
42
+ const xml = renderRssFeed({
43
+ title: section.siteTitle ?? section.title,
44
+ description: section.siteDescription ?? config.description ?? "",
45
+ link: toAbsolute(section.prefix),
46
+ feedLink: toAbsolute(`${section.prefix}rss.xml`),
47
+ items,
48
+ });
49
+ return new Response(xml, {
50
+ headers: { "Content-Type": "application/rss+xml; charset=utf-8" },
51
+ });
52
+ },
53
+ },
54
+ },
55
+ });
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiJHNlY3Rpb24ucnNzWy5deG1sLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL3JvdXRlcy8kc2VjdGlvbi5yc3NbLl14bWwudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQTtBQUN6QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUE7QUFDeEQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFBO0FBQzNFLE9BQU8sRUFBRSxhQUFhLEVBQWdCLE1BQU0sbUJBQW1CLENBQUE7QUFFL0QsTUFBTSxlQUFlLEdBQUcsRUFBRSxDQUFBO0FBRTFCLE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUN4RCxNQUFNLEVBQUU7UUFDTixRQUFRLEVBQUU7WUFDUixHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsTUFBTSxFQUFtQyxFQUFFLEVBQUU7Z0JBQ3pELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ2pCLE9BQU8sSUFBSSxRQUFRLENBQUMsMkNBQTJDLEVBQUU7d0JBQy9ELE1BQU0sRUFBRSxHQUFHO3FCQUNaLENBQUMsQ0FBQTtnQkFDSixDQUFDO2dCQUNELE1BQU0sTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLE9BQU8sR0FBRyxDQUFBO2dCQUNwQyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLElBQUksQ0FDbkMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FDOUMsQ0FBQTtnQkFDRCxJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssTUFBTSxFQUFFLENBQUM7b0JBQ3hDLE9BQU8sSUFBSSxRQUFRLENBQUMsV0FBVyxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUE7Z0JBQ25ELENBQUM7Z0JBQ0QsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxDQUFBO2dCQUM1QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQTtnQkFDOUIsTUFBTSxVQUFVLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEVBQUUsQ0FBQTtnQkFFNUQsTUFBTSxLQUFLLEdBQUcsbUJBQW1CLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUE7Z0JBQzNELE1BQU0sS0FBSyxHQUFjLEVBQUUsQ0FBQTtnQkFDM0IsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztvQkFDekIsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLGVBQWU7d0JBQUUsTUFBSztvQkFDMUMsTUFBTSxPQUFPLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLENBQUE7b0JBQ3pELElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSTt3QkFBRSxTQUFRO29CQUM1QixNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFBO29CQUNyQyxLQUFLLENBQUMsSUFBSSxDQUFDO3dCQUNULEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSzt3QkFDcEIsSUFBSTt3QkFDSixJQUFJLEVBQUUsSUFBSTt3QkFDVixXQUFXLEVBQUUsT0FBTyxDQUFDLFdBQVc7d0JBQ2hDLE9BQU8sRUFBRSxPQUFPLENBQUMsSUFBSTt3QkFDckIsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO3dCQUN0QixVQUFVLEVBQUUsT0FBTyxDQUFDLElBQUk7cUJBQ3pCLENBQUMsQ0FBQTtnQkFDSixDQUFDO2dCQUVELE1BQU0sR0FBRyxHQUFHLGFBQWEsQ0FBQztvQkFDeEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxTQUFTLElBQUksT0FBTyxDQUFDLEtBQUs7b0JBQ3pDLFdBQVcsRUFBRSxPQUFPLENBQUMsZUFBZSxJQUFJLE1BQU0sQ0FBQyxXQUFXLElBQUksRUFBRTtvQkFDaEUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO29CQUNoQyxRQUFRLEVBQUUsVUFBVSxDQUFDLEdBQUcsT0FBTyxDQUFDLE1BQU0sU0FBUyxDQUFDO29CQUNoRCxLQUFLO2lCQUNOLENBQUMsQ0FBQTtnQkFFRixPQUFPLElBQUksUUFBUSxDQUFDLEdBQUcsRUFBRTtvQkFDdkIsT0FBTyxFQUFFLEVBQUUsY0FBYyxFQUFFLG9DQUFvQyxFQUFFO2lCQUNsRSxDQUFDLENBQUE7WUFDSixDQUFDO1NBQ0Y7S0FDRjtDQUNGLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCJsaXZlbWFyazp2aXJ0dWFsXCJcbmltcG9ydCB7IGNyZWF0ZUZpbGVSb3V0ZSB9IGZyb20gXCJAdGFuc3RhY2svcmVhY3Qtcm91dGVyXCJcbmltcG9ydCB7IHNlY3Rpb25GbGF0QXJ0aWNsZXMsIHNvcnRlZEFydGljbGVzIH0gZnJvbSBcIi4uL2NvbnRlbnQvYXJ0aWNsZS50c1wiXG5pbXBvcnQgeyByZW5kZXJSc3NGZWVkLCB0eXBlIFJzc0l0ZW0gfSBmcm9tIFwiLi4vaGVscGVycy9yc3MudHNcIlxuXG5jb25zdCBGRUVEX0lURU1fTElNSVQgPSAyMFxuXG5leHBvcnQgY29uc3QgUm91dGUgPSBjcmVhdGVGaWxlUm91dGUoXCIvJHNlY3Rpb24vcnNzLnhtbFwiKSh7XG4gIHNlcnZlcjoge1xuICAgIGhhbmRsZXJzOiB7XG4gICAgICBHRVQ6IGFzeW5jICh7IHBhcmFtcyB9OiB7IHBhcmFtczogeyBzZWN0aW9uOiBzdHJpbmcgfSB9KSA9PiB7XG4gICAgICAgIGlmICghY29uZmlnLnNpdGUpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKFwiUlNTIHJlcXVpcmVzIGBzaXRlYCBpbiBsaXZlbWFyay5jb25maWcudHNcIiwge1xuICAgICAgICAgICAgc3RhdHVzOiA0MDQsXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcmVmaXggPSBgLyR7cGFyYW1zLnNlY3Rpb259L2BcbiAgICAgICAgY29uc3Qgc2VjdGlvbiA9IGNvbmZpZy5zZWN0aW9ucz8uZmluZChcbiAgICAgICAgICBzID0+IHMudHlwZSA9PT0gXCJibG9nXCIgJiYgcy5wcmVmaXggPT09IHByZWZpeCxcbiAgICAgICAgKVxuICAgICAgICBpZiAoIXNlY3Rpb24gfHwgc2VjdGlvbi50eXBlICE9PSBcImJsb2dcIikge1xuICAgICAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoXCJOb3QgZm91bmRcIiwgeyBzdGF0dXM6IDQwNCB9KVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGhvc3QgPSBjb25maWcuc2l0ZS5yZXBsYWNlKC9cXC8rJC8sIFwiXCIpXG4gICAgICAgIGNvbnN0IGJhc2UgPSBjb25maWcuYmFzZSA/PyBcIlwiXG4gICAgICAgIGNvbnN0IHRvQWJzb2x1dGUgPSAocGF0aDogc3RyaW5nKSA9PiBgJHtob3N0fSR7YmFzZX0ke3BhdGh9YFxuXG4gICAgICAgIGNvbnN0IHBhdGhzID0gc2VjdGlvbkZsYXRBcnRpY2xlcy5nZXQoc2VjdGlvbi5wcmVmaXgpID8/IFtdXG4gICAgICAgIGNvbnN0IGl0ZW1zOiBSc3NJdGVtW10gPSBbXVxuICAgICAgICBmb3IgKGNvbnN0IHBhdGggb2YgcGF0aHMpIHtcbiAgICAgICAgICBpZiAoaXRlbXMubGVuZ3RoID49IEZFRURfSVRFTV9MSU1JVCkgYnJlYWtcbiAgICAgICAgICBjb25zdCBhcnRpY2xlID0gc29ydGVkQXJ0aWNsZXMuZmluZChhID0+IGEucGF0aCA9PT0gcGF0aClcbiAgICAgICAgICBpZiAoIWFydGljbGU/LmRhdGUpIGNvbnRpbnVlXG4gICAgICAgICAgY29uc3QgbGluayA9IHRvQWJzb2x1dGUoYXJ0aWNsZS5wYXRoKVxuICAgICAgICAgIGl0ZW1zLnB1c2goe1xuICAgICAgICAgICAgdGl0bGU6IGFydGljbGUudGl0bGUsXG4gICAgICAgICAgICBsaW5rLFxuICAgICAgICAgICAgZ3VpZDogbGluayxcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBhcnRpY2xlLmRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgcHViRGF0ZTogYXJ0aWNsZS5kYXRlLFxuICAgICAgICAgICAgYXV0aG9yOiBhcnRpY2xlLmF1dGhvcixcbiAgICAgICAgICAgIGNhdGVnb3JpZXM6IGFydGljbGUudGFncyxcbiAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgeG1sID0gcmVuZGVyUnNzRmVlZCh7XG4gICAgICAgICAgdGl0bGU6IHNlY3Rpb24uc2l0ZVRpdGxlID8/IHNlY3Rpb24udGl0bGUsXG4gICAgICAgICAgZGVzY3JpcHRpb246IHNlY3Rpb24uc2l0ZURlc2NyaXB0aW9uID8/IGNvbmZpZy5kZXNjcmlwdGlvbiA/PyBcIlwiLFxuICAgICAgICAgIGxpbms6IHRvQWJzb2x1dGUoc2VjdGlvbi5wcmVmaXgpLFxuICAgICAgICAgIGZlZWRMaW5rOiB0b0Fic29sdXRlKGAke3NlY3Rpb24ucHJlZml4fXJzcy54bWxgKSxcbiAgICAgICAgICBpdGVtcyxcbiAgICAgICAgfSlcblxuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKHhtbCwge1xuICAgICAgICAgIGhlYWRlcnM6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9yc3MreG1sOyBjaGFyc2V0PXV0Zi04XCIgfSxcbiAgICAgICAgfSlcbiAgICAgIH0sXG4gICAgfSxcbiAgfSxcbn0pXG4iXX0=
@@ -16,6 +16,16 @@ import markdownCss from "../styles/markdown.css?url";
16
16
  export const Route = createRootRoute({
17
17
  head: () => {
18
18
  const favicon = prefixUrl(config.favicon ?? config.logo ?? defaultFavicon, config.base);
19
+ const feedLinks = config.site
20
+ ? (config.sections ?? [])
21
+ .filter(s => s.type === "blog")
22
+ .map(s => ({
23
+ rel: "alternate",
24
+ type: "application/rss+xml",
25
+ title: `${s.siteTitle ?? s.title} RSS Feed`,
26
+ href: prefixUrl(`${s.prefix}rss.xml`, config.base),
27
+ }))
28
+ : [];
19
29
  return {
20
30
  meta: [
21
31
  { charSet: "utf-8" },
@@ -38,6 +48,7 @@ export const Route = createRootRoute({
38
48
  { rel: "shortcut icon", href: favicon, type: faviconType(favicon) },
39
49
  { rel: "stylesheet", href: generalCss },
40
50
  { rel: "stylesheet", href: markdownCss },
51
+ ...feedLinks,
41
52
  ],
42
53
  };
43
54
  },
@@ -69,4 +80,4 @@ function Document(props) {
69
80
  ] })
70
81
  ] }));
71
82
  }
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX19yb290LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL3JvdXRlcy9fX3Jvb3QudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMEJBQTBCLENBQUE7QUFDM0QsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZ0NBQWdDLENBQUE7QUFDeEUsT0FBTyxFQUNMLGVBQWUsRUFDZixXQUFXLEVBQ1gsTUFBTSxFQUNOLE9BQU8sRUFDUCxRQUFRLEdBQ1QsTUFBTSx3QkFBd0IsQ0FBQTtBQUMvQixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQTtBQUU3RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0seUJBQTBCLENBQUE7QUFDakQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXdDLENBQUE7QUFDN0UsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUE0QixDQUFBO0FBQ3JELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx1QkFBd0IsQ0FBQTtBQUNoRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFDbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFBO0FBQ3BELE9BQU8sY0FBYyxNQUFNLG9CQUFvQixDQUFBO0FBQy9DLE9BQU8sVUFBVSxNQUFNLDJCQUEyQixDQUFBO0FBQ2xELE9BQU8sV0FBVyxNQUFNLDRCQUE0QixDQUFBO0FBRXBELE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUM7SUFDbkMsSUFBSSxFQUFFLEdBQUcsRUFBRTtRQUNULE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FDdkIsTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLGNBQWMsRUFDL0MsTUFBTSxDQUFDLElBQUks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dmlydHVhbFwiXG5pbXBvcnQgeyBUYW5TdGFja0RldnRvb2xzIH0gZnJvbSBcIkB0YW5zdGFjay9yZWFjdC1kZXZ0b29sc1wiXG5pbXBvcnQgeyBSZWFjdFF1ZXJ5RGV2dG9vbHNQYW5lbCB9IGZyb20gXCJAdGFuc3RhY2svcmVhY3QtcXVlcnktZGV2dG9vbHNcIlxuaW1wb3J0IHtcbiAgY3JlYXRlUm9vdFJvdXRlLFxuICBIZWFkQ29udGVudCxcbiAgT3V0bGV0LFxuICBTY3JpcHRzLFxuICB1c2VNYXRjaCxcbn0gZnJvbSBcIkB0YW5zdGFjay9yZWFjdC1yb3V0ZXJcIlxuaW1wb3J0IHsgVGFuU3RhY2tSb3V0ZXJEZXZ0b29sc1BhbmVsIH0gZnJvbSBcIkB0YW5zdGFjay9yZWFjdC1yb3V0ZXItZGV2dG9vbHNcIlxuaW1wb3J0IHR5cGUgKiBhcyBSZWFjdCBmcm9tIFwicmVhY3RcIlxuaW1wb3J0IHsgTGF5b3V0IH0gZnJvbSBcIi4uL2NvbXBvbmVudHMvTGF5b3V0LnRzeFwiXG5pbXBvcnQgeyBEZWZhdWx0Q2F0Y2hCb3VuZGFyeSB9IGZyb20gXCIuLi9jb21wb25lbnRzL0RlZmF1bHRDYXRjaEJvdW5kYXJ5LnRzeFwiXG5pbXBvcnQgeyBOb3RGb3VuZCB9IGZyb20gXCIuLi9jb21wb25lbnRzL05vdEZvdW5kLnRzeFwiXG5pbXBvcnQgeyBUb2FzdGVyIH0gZnJvbSBcIi4uL2VsZW1lbnRzL3Nvbm5lci50c3hcIlxuaW1wb3J0IHsgZmF2aWNvblR5cGUgfSBmcm9tIFwiLi4vaGVscGVycy9mYXZpY29uLnRzXCJcbmltcG9ydCB7IHByZWZpeFVybCB9IGZyb20gXCIuLi9oZWxwZXJzL3ByZWZpeC11cmwudHNcIlxuaW1wb3J0IGRlZmF1bHRGYXZpY29uIGZyb20gXCIuLi9hc3NldHMvbG9nby5zdmdcIlxuaW1wb3J0IGdlbmVyYWxDc3MgZnJvbSBcIi4uL3N0eWxlcy9nZW5lcmFsLmNzcz91cmxcIlxuaW1wb3J0IG1hcmtkb3duQ3NzIGZyb20gXCIuLi9zdHlsZXMvbWFya2Rvd24uY3NzP3VybFwiXG5cbmV4cG9ydCBjb25zdCBSb3V0ZSA9IGNyZWF0ZVJvb3RSb3V0ZSh7XG4gIGhlYWQ6ICgpID0+IHtcbiAgICBjb25zdCBmYXZpY29uID0gcHJlZml4VXJsKFxuICAgICAgY29uZmlnLmZhdmljb24gPz8gY29uZmlnLmxvZ28gPz8gZGVmYXVsdEZhdmljb24sXG4gICAgICBjb25maWcuYmFzZSxcbiAgICApXG4gICAgcmV0dXJuIHtcbiAgICAgIG1ldGE6IFtcbiAgICAgICAgeyBjaGFyU2V0OiBcInV0Zi04XCIgfSxcbiAgICAgICAgeyB0aXRsZTogY29uZmlnLnRpdGxlIH0sXG4gICAgICAgIHsgbmFtZTogXCJkZXNjcmlwdGlvblwiLCBjb250ZW50OiBjb25maWcuZGVzY3JpcHRpb24gfSxcbiAgICAgICAgeyBwcm9wZXJ0eTogXCJvZzp0aXRsZVwiLCBjb250ZW50OiBjb25maWcudGl0bGUgfSxcbiAgICAgICAge1xuICAgICAgICAgIHByb3BlcnR5OiBcIm9nOmRlc2NyaXB0aW9uXCIsXG4gICAgICAgICAgY29udGVudDogY29uZmlnLmRlc2NyaXB0aW9uLFxuICAgICAgICB9LFxuICAgICAgICB7IHByb3BlcnR5OiBcIm9nOnNpdGVfbmFtZVwiLCBjb250ZW50OiBjb25maWcudGl0bGUgfSxcbiAgICAgICAgeyBwcm9wZXJ0eTogXCJvZzp0eXBlXCIsIGNvbnRlbnQ6IFwid2Vic2l0ZVwiIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBuYW1lOiBcInZpZXdwb3J0XCIsXG4gICAgICAgICAgY29udGVudDogXCJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MVwiLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxpbmtzOiBbXG4gICAgICAgIHsgcmVsOiBcImljb25cIiwgaHJlZjogZmF2aWNvbiwgdHlwZTogZmF2aWNvblR5cGUoZmF2aWNvbikgfSxcbiAgICAgICAgeyByZWw6IFwic2hvcnRjdXQgaWNvblwiLCBocmVmOiBmYXZpY29uLCB0eXBlOiBmYXZpY29uVHlwZShmYXZpY29uKSB9LFxuICAgICAgICB7IHJlbDogXCJzdHlsZXNoZWV0XCIsIGhyZWY6IGdlbmVyYWxDc3MgfSxcbiAgICAgICAgeyByZWw6IFwic3R5bGVzaGVldFwiLCBocmVmOiBtYXJrZG93bkNzcyB9LFxuICAgICAgXSxcbiAgICB9XG4gIH0sXG4gIG5vdEZvdW5kQ29tcG9uZW50OiAoKSA9PiA8Tm90Rm91bmQgLz4sXG4gIGVycm9yQ29tcG9uZW50OiBwcm9wcyA9PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxEb2N1bWVudD5cbiAgICAgICAgPERlZmF1bHRDYXRjaEJvdW5kYXJ5IHsuLi5wcm9wc30gLz5cbiAgICAgIDwvRG9jdW1lbnQ+XG4gICAgKVxuICB9LFxuICBjb21wb25lbnQ6ICgpID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgPERvY3VtZW50PlxuICAgICAgICA8T3V0bGV0IC8+XG4gICAgICA8L0RvY3VtZW50PlxuICAgIClcbiAgfSxcbn0pXG5cbmZ1bmN0aW9uIERvY3VtZW50KHByb3BzOiB7IGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGUgfSkge1xuICBjb25zdCBhcnRpY2xlUm91dGUgPSB1c2VNYXRjaCh7IGZyb206IFwiLyRcIiwgc2hvdWxkVGhyb3c6IGZhbHNlIH0pXG4gIGNvbnN0IHdpdGhTaWRlYmFyID0gYXJ0aWNsZVJvdXRlPy5sb2FkZXJEYXRhPy5zaWRlYmFyXG5cbiAgcmV0dXJuIChcbiAgICA8aHRtbCBsYW5nPVwiZW5cIj5cbiAgICAgIDxoZWFkPlxuICAgICAgICA8SGVhZENvbnRlbnQgLz5cbiAgICAgIDwvaGVhZD5cbiAgICAgIDxib2R5PlxuICAgICAgICA8TGF5b3V0IHdpdGhTaWRlYmFyPXt3aXRoU2lkZWJhcn0+e3Byb3BzLmNoaWxkcmVufTwvTGF5b3V0PlxuICAgICAgICA8VG9hc3RlciBwb3NpdGlvbj1cInRvcC1jZW50ZXJcIiAvPlxuICAgICAgICA8VGFuU3RhY2tEZXZ0b29sc1xuICAgICAgICAgIGNvbmZpZz17eyBoaWRlVW50aWxIb3ZlcjogdHJ1ZSwgcG9zaXRpb246IFwiYm90dG9tLWxlZnRcIiB9fVxuICAgICAgICAgIHBsdWdpbnM9e1tcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbmFtZTogXCJUYW5TdGFjayBRdWVyeVwiLFxuICAgICAgICAgICAgICByZW5kZXI6IDxSZWFjdFF1ZXJ5RGV2dG9vbHNQYW5lbCAvPixcbiAgICAgICAgICAgICAgZGVmYXVsdE9wZW46IHRydWUsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBuYW1lOiBcIlRhblN0YWNrIFJvdXRlclwiLFxuICAgICAgICAgICAgICByZW5kZXI6IDxUYW5TdGFja1JvdXRlckRldnRvb2xzUGFuZWwgLz4sXG4gICAgICAgICAgICAgIGRlZmF1bHRPcGVuOiBmYWxzZSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXX1cbiAgICAgICAgLz5cbiAgICAgICAgPFNjcmlwdHMgLz5cbiAgICAgIDwvYm9keT5cbiAgICA8L2h0bWw+XG4gIClcbn1cbiJdfQ==
83
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX19yb290LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc291cmNlL3JvdXRlcy9fX3Jvb3QudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUE7QUFDekMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMEJBQTBCLENBQUE7QUFDM0QsT0FBTyxFQUFFLHVCQUF1QixFQUFFLE1BQU0sZ0NBQWdDLENBQUE7QUFDeEUsT0FBTyxFQUNMLGVBQWUsRUFDZixXQUFXLEVBQ1gsTUFBTSxFQUNOLE9BQU8sRUFDUCxRQUFRLEdBQ1QsTUFBTSx3QkFBd0IsQ0FBQTtBQUMvQixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQTtBQUU3RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0seUJBQTBCLENBQUE7QUFDakQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUNBQXdDLENBQUE7QUFDN0UsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUE0QixDQUFBO0FBQ3JELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSx1QkFBd0IsQ0FBQTtBQUNoRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFDbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFBO0FBQ3BELE9BQU8sY0FBYyxNQUFNLG9CQUFvQixDQUFBO0FBQy9DLE9BQU8sVUFBVSxNQUFNLDJCQUEyQixDQUFBO0FBQ2xELE9BQU8sV0FBVyxNQUFNLDRCQUE0QixDQUFBO0FBRXBELE1BQU0sQ0FBQyxNQUFNLEtBQUssR0FBRyxlQUFlLENBQUM7SUFDbkMsSUFBSSxFQUFFLEdBQUcsRUFBRTtRQUNULE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FDdkIsTUFBTSxDQUFDLE9BQU8sSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLGNBQWMsRUFDL0MsTUFBTSxDQUFDLElBQUks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LEVBQzNELEtBQUMsT0FBTyxJQUFDLFFBQVEsRUFBQyxZQUFZLEdBQUcsRUFDakMsS0FBQyxnQkFBZ0IsSUFDZixNQUFNLEVBQUUsRUFBRSxjQUFjLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsRUFDekQsT0FBTyxFQUFFOzRCQUNQO2dDQUNFLElBQUksRUFBRSxnQkFBZ0I7Z0NBQ3RCLE1BQU0sRUFBRSxLQUFDLHVCQUF1QixLQUFHO2dDQUNuQyxXQUFXLEVBQUUsSUFBSTs2QkFDbEI7NEJBQ0Q7Z0NBQ0UsSUFBSSxFQUFFLGlCQUFpQjtnQ0FDdkIsTUFBTSxFQUFFLEtBQUMsMkJBQTJCLEtBQUc7Z0NBQ3ZDLFdBQVcsRUFBRSxLQUFLOzZCQUNuQjt5QkFDRixHQUNELEVBQ0YsS0FBQyxPQUFPLEtBQUc7b0JBQ047WUFDRixDQUNSLENBQUE7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY29uZmlnIH0gZnJvbSBcImxpdmVtYXJrOnZpcnR1YWxcIlxuaW1wb3J0IHsgVGFuU3RhY2tEZXZ0b29scyB9IGZyb20gXCJAdGFuc3RhY2svcmVhY3QtZGV2dG9vbHNcIlxuaW1wb3J0IHsgUmVhY3RRdWVyeURldnRvb2xzUGFuZWwgfSBmcm9tIFwiQHRhbnN0YWNrL3JlYWN0LXF1ZXJ5LWRldnRvb2xzXCJcbmltcG9ydCB7XG4gIGNyZWF0ZVJvb3RSb3V0ZSxcbiAgSGVhZENvbnRlbnQsXG4gIE91dGxldCxcbiAgU2NyaXB0cyxcbiAgdXNlTWF0Y2gsXG59IGZyb20gXCJAdGFuc3RhY2svcmVhY3Qtcm91dGVyXCJcbmltcG9ydCB7IFRhblN0YWNrUm91dGVyRGV2dG9vbHNQYW5lbCB9IGZyb20gXCJAdGFuc3RhY2svcmVhY3Qtcm91dGVyLWRldnRvb2xzXCJcbmltcG9ydCB0eXBlICogYXMgUmVhY3QgZnJvbSBcInJlYWN0XCJcbmltcG9ydCB7IExheW91dCB9IGZyb20gXCIuLi9jb21wb25lbnRzL0xheW91dC50c3hcIlxuaW1wb3J0IHsgRGVmYXVsdENhdGNoQm91bmRhcnkgfSBmcm9tIFwiLi4vY29tcG9uZW50cy9EZWZhdWx0Q2F0Y2hCb3VuZGFyeS50c3hcIlxuaW1wb3J0IHsgTm90Rm91bmQgfSBmcm9tIFwiLi4vY29tcG9uZW50cy9Ob3RGb3VuZC50c3hcIlxuaW1wb3J0IHsgVG9hc3RlciB9IGZyb20gXCIuLi9lbGVtZW50cy9zb25uZXIudHN4XCJcbmltcG9ydCB7IGZhdmljb25UeXBlIH0gZnJvbSBcIi4uL2hlbHBlcnMvZmF2aWNvbi50c1wiXG5pbXBvcnQgeyBwcmVmaXhVcmwgfSBmcm9tIFwiLi4vaGVscGVycy9wcmVmaXgtdXJsLnRzXCJcbmltcG9ydCBkZWZhdWx0RmF2aWNvbiBmcm9tIFwiLi4vYXNzZXRzL2xvZ28uc3ZnXCJcbmltcG9ydCBnZW5lcmFsQ3NzIGZyb20gXCIuLi9zdHlsZXMvZ2VuZXJhbC5jc3M/dXJsXCJcbmltcG9ydCBtYXJrZG93bkNzcyBmcm9tIFwiLi4vc3R5bGVzL21hcmtkb3duLmNzcz91cmxcIlxuXG5leHBvcnQgY29uc3QgUm91dGUgPSBjcmVhdGVSb290Um91dGUoe1xuICBoZWFkOiAoKSA9PiB7XG4gICAgY29uc3QgZmF2aWNvbiA9IHByZWZpeFVybChcbiAgICAgIGNvbmZpZy5mYXZpY29uID8/IGNvbmZpZy5sb2dvID8/IGRlZmF1bHRGYXZpY29uLFxuICAgICAgY29uZmlnLmJhc2UsXG4gICAgKVxuICAgIGNvbnN0IGZlZWRMaW5rcyA9IGNvbmZpZy5zaXRlXG4gICAgICA/IChjb25maWcuc2VjdGlvbnMgPz8gW10pXG4gICAgICAgICAgLmZpbHRlcihzID0+IHMudHlwZSA9PT0gXCJibG9nXCIpXG4gICAgICAgICAgLm1hcChzID0+ICh7XG4gICAgICAgICAgICByZWw6IFwiYWx0ZXJuYXRlXCIsXG4gICAgICAgICAgICB0eXBlOiBcImFwcGxpY2F0aW9uL3Jzcyt4bWxcIixcbiAgICAgICAgICAgIHRpdGxlOiBgJHtzLnNpdGVUaXRsZSA/PyBzLnRpdGxlfSBSU1MgRmVlZGAsXG4gICAgICAgICAgICBocmVmOiBwcmVmaXhVcmwoYCR7cy5wcmVmaXh9cnNzLnhtbGAsIGNvbmZpZy5iYXNlKSxcbiAgICAgICAgICB9KSlcbiAgICAgIDogW11cbiAgICByZXR1cm4ge1xuICAgICAgbWV0YTogW1xuICAgICAgICB7IGNoYXJTZXQ6IFwidXRmLThcIiB9LFxuICAgICAgICB7IHRpdGxlOiBjb25maWcudGl0bGUgfSxcbiAgICAgICAgeyBuYW1lOiBcImRlc2NyaXB0aW9uXCIsIGNvbnRlbnQ6IGNvbmZpZy5kZXNjcmlwdGlvbiB9LFxuICAgICAgICB7IHByb3BlcnR5OiBcIm9nOnRpdGxlXCIsIGNvbnRlbnQ6IGNvbmZpZy50aXRsZSB9LFxuICAgICAgICB7XG4gICAgICAgICAgcHJvcGVydHk6IFwib2c6ZGVzY3JpcHRpb25cIixcbiAgICAgICAgICBjb250ZW50OiBjb25maWcuZGVzY3JpcHRpb24sXG4gICAgICAgIH0sXG4gICAgICAgIHsgcHJvcGVydHk6IFwib2c6c2l0ZV9uYW1lXCIsIGNvbnRlbnQ6IGNvbmZpZy50aXRsZSB9LFxuICAgICAgICB7IHByb3BlcnR5OiBcIm9nOnR5cGVcIiwgY29udGVudDogXCJ3ZWJzaXRlXCIgfSxcbiAgICAgICAge1xuICAgICAgICAgIG5hbWU6IFwidmlld3BvcnRcIixcbiAgICAgICAgICBjb250ZW50OiBcIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xXCIsXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgICAgbGlua3M6IFtcbiAgICAgICAgeyByZWw6IFwiaWNvblwiLCBocmVmOiBmYXZpY29uLCB0eXBlOiBmYXZpY29uVHlwZShmYXZpY29uKSB9LFxuICAgICAgICB7IHJlbDogXCJzaG9ydGN1dCBpY29uXCIsIGhyZWY6IGZhdmljb24sIHR5cGU6IGZhdmljb25UeXBlKGZhdmljb24pIH0sXG4gICAgICAgIHsgcmVsOiBcInN0eWxlc2hlZXRcIiwgaHJlZjogZ2VuZXJhbENzcyB9LFxuICAgICAgICB7IHJlbDogXCJzdHlsZXNoZWV0XCIsIGhyZWY6IG1hcmtkb3duQ3NzIH0sXG4gICAgICAgIC4uLmZlZWRMaW5rcyxcbiAgICAgIF0sXG4gICAgfVxuICB9LFxuICBub3RGb3VuZENvbXBvbmVudDogKCkgPT4gPE5vdEZvdW5kIC8+LFxuICBlcnJvckNvbXBvbmVudDogcHJvcHMgPT4ge1xuICAgIHJldHVybiAoXG4gICAgICA8RG9jdW1lbnQ+XG4gICAgICAgIDxEZWZhdWx0Q2F0Y2hCb3VuZGFyeSB7Li4ucHJvcHN9IC8+XG4gICAgICA8L0RvY3VtZW50PlxuICAgIClcbiAgfSxcbiAgY29tcG9uZW50OiAoKSA9PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxEb2N1bWVudD5cbiAgICAgICAgPE91dGxldCAvPlxuICAgICAgPC9Eb2N1bWVudD5cbiAgICApXG4gIH0sXG59KVxuXG5mdW5jdGlvbiBEb2N1bWVudChwcm9wczogeyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0pIHtcbiAgY29uc3QgYXJ0aWNsZVJvdXRlID0gdXNlTWF0Y2goeyBmcm9tOiBcIi8kXCIsIHNob3VsZFRocm93OiBmYWxzZSB9KVxuICBjb25zdCB3aXRoU2lkZWJhciA9IGFydGljbGVSb3V0ZT8ubG9hZGVyRGF0YT8uc2lkZWJhclxuXG4gIHJldHVybiAoXG4gICAgPGh0bWwgbGFuZz1cImVuXCI+XG4gICAgICA8aGVhZD5cbiAgICAgICAgPEhlYWRDb250ZW50IC8+XG4gICAgICA8L2hlYWQ+XG4gICAgICA8Ym9keT5cbiAgICAgICAgPExheW91dCB3aXRoU2lkZWJhcj17d2l0aFNpZGViYXJ9Pntwcm9wcy5jaGlsZHJlbn08L0xheW91dD5cbiAgICAgICAgPFRvYXN0ZXIgcG9zaXRpb249XCJ0b3AtY2VudGVyXCIgLz5cbiAgICAgICAgPFRhblN0YWNrRGV2dG9vbHNcbiAgICAgICAgICBjb25maWc9e3sgaGlkZVVudGlsSG92ZXI6IHRydWUsIHBvc2l0aW9uOiBcImJvdHRvbS1sZWZ0XCIgfX1cbiAgICAgICAgICBwbHVnaW5zPXtbXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIG5hbWU6IFwiVGFuU3RhY2sgUXVlcnlcIixcbiAgICAgICAgICAgICAgcmVuZGVyOiA8UmVhY3RRdWVyeURldnRvb2xzUGFuZWwgLz4sXG4gICAgICAgICAgICAgIGRlZmF1bHRPcGVuOiB0cnVlLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgbmFtZTogXCJUYW5TdGFjayBSb3V0ZXJcIixcbiAgICAgICAgICAgICAgcmVuZGVyOiA8VGFuU3RhY2tSb3V0ZXJEZXZ0b29sc1BhbmVsIC8+LFxuICAgICAgICAgICAgICBkZWZhdWx0T3BlbjogZmFsc2UsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF19XG4gICAgICAgIC8+XG4gICAgICAgIDxTY3JpcHRzIC8+XG4gICAgICA8L2JvZHk+XG4gICAgPC9odG1sPlxuICApXG59XG4iXX0=
@@ -9,6 +9,18 @@ import { loadConfig } from "./actions/config/load.js";
9
9
  import { livemark } from "./plugins/vite-livemark.js";
10
10
  import { robots } from "./plugins/vite-robots.js";
11
11
  const config = await loadConfig();
12
+ // Per-blog-section RSS feed paths to prerender. Gated on `config.site`
13
+ // because feed URLs are absolute (matching the sitemap/robots.txt gate)
14
+ // and the route returns 404 without it anyway. Excluded from the sitemap
15
+ // since `.xml` payloads don't belong in a sitemap.
16
+ const blogFeedPages = config.site
17
+ ? (config.sections ?? [])
18
+ .filter(s => s.type === "blog")
19
+ .map(s => ({
20
+ path: `${config.base ?? ""}${s.prefix}rss.xml`,
21
+ sitemap: { exclude: true },
22
+ }))
23
+ : [];
12
24
  export default defineConfig({
13
25
  plugins: [
14
26
  livemark({ config }),
@@ -21,7 +33,10 @@ export default defineConfig({
21
33
  // Seed path must match what the crawler produces (router-emitted
22
34
  // hrefs include the basepath), otherwise prerender records both
23
35
  // shapes and the sitemap ends up with duplicate entries.
24
- pages: [{ path: config.base ? `${config.base}/` : "/" }],
36
+ pages: [
37
+ { path: config.base ? `${config.base}/` : "/" },
38
+ ...blogFeedPages,
39
+ ],
25
40
  // Disable route-tree auto-discovery: it produces basepath-naive
26
41
  // paths (e.g. `/`) that duplicate the crawl-derived prefixed paths,
27
42
  // bloating pages.json and sitemap. Crawling from the seed already
@@ -43,4 +58,4 @@ export default defineConfig({
43
58
  svgr(),
44
59
  ],
45
60
  });
46
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidml0ZS5jb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2Uvdml0ZS5jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxrQkFBa0IsTUFBTSwyQkFBMkIsQ0FBQTtBQUMxRCxPQUFPLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFDbEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFBO0FBQ2pFLE9BQU8sS0FBSyxNQUFNLHNCQUFzQixDQUFBO0FBQ3hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFDbkMsT0FBTyxJQUFJLE1BQU0sa0JBQWtCLENBQUE7QUFDbkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFBO0FBQ3JELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQTtBQUNyRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMEJBQTBCLENBQUE7QUFFakQsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLEVBQUUsQ0FBQTtBQUVqQyxlQUFlLFlBQVksQ0FBQztJQUMxQixPQUFPLEVBQUU7UUFDUCxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUNwQixNQUFNLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztRQUNsQixRQUFRLEVBQUU7UUFDVixRQUFRLEVBQUU7UUFDVixrQkFBa0IsQ0FBQyxFQUFFLFVBQVUsRUFBRSx3QkFBd0IsRUFBRSxDQUFDO1FBQzVELGFBQWEsQ0FBQztZQUNaLFlBQVksRUFBRSxHQUFHO1lBQ2pCLGlFQUFpRTtZQUNqRSxnRUFBZ0U7WUFDaEUseURBQXlEO1lBQ3pELEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUN4RCxnRUFBZ0U7WUFDaEUsb0VBQW9FO1lBQ3BFLGtFQUFrRTtZQUNsRSw2QkFBNkI7WUFDN0IsU0FBUyxFQUFFO2dCQUNULE9BQU8sRUFBRSxJQUFJO2dCQUNiLFVBQVUsRUFBRSxJQUFJO2dCQUNoQix3QkFBd0IsRUFBRSxLQUFLO2FBQ2hDO1lBQ0QsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJO2dCQUNsQixDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxFQUFFO2dCQUN0QyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFO1lBQ3RCLE1BQU0sRUFBRTtnQkFDTixrQkFBa0IsRUFBRSxrQkFBa0I7Z0JBQ3RDLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSTthQUN0QjtTQUNGLENBQUM7UUFDRixLQUFLLEVBQUU7UUFDUCxJQUFJLEVBQUU7S0FDUDtDQUNGLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBjb250ZW50Q29sbGVjdGlvbnMgZnJvbSBcIkBjb250ZW50LWNvbGxlY3Rpb25zL3ZpdGVcIlxuaW1wb3J0IHRhaWx3aW5kIGZyb20gXCJAdGFpbHdpbmRjc3Mvdml0ZVwiXG5pbXBvcnQgeyBkZXZ0b29scyB9IGZyb20gXCJAdGFuc3RhY2svZGV2dG9vbHMtdml0ZVwiXG5pbXBvcnQgeyB0YW5zdGFja1N0YXJ0IH0gZnJvbSBcIkB0YW5zdGFjay9yZWFjdC1zdGFydC9wbHVnaW4vdml0ZVwiXG5pbXBvcnQgcmVhY3QgZnJvbSBcIkB2aXRlanMvcGx1Z2luLXJlYWN0XCJcbmltcG9ydCB7IGRlZmluZUNvbmZpZyB9IGZyb20gXCJ2aXRlXCJcbmltcG9ydCBzdmdyIGZyb20gXCJ2aXRlLXBsdWdpbi1zdmdyXCJcbmltcG9ydCB7IGxvYWRDb25maWcgfSBmcm9tIFwiLi9hY3Rpb25zL2NvbmZpZy9sb2FkLnRzXCJcbmltcG9ydCB7IGxpdmVtYXJrIH0gZnJvbSBcIi4vcGx1Z2lucy92aXRlLWxpdmVtYXJrLnRzXCJcbmltcG9ydCB7IHJvYm90cyB9IGZyb20gXCIuL3BsdWdpbnMvdml0ZS1yb2JvdHMudHNcIlxuXG5jb25zdCBjb25maWcgPSBhd2FpdCBsb2FkQ29uZmlnKClcblxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgcGx1Z2luczogW1xuICAgIGxpdmVtYXJrKHsgY29uZmlnIH0pLFxuICAgIHJvYm90cyh7IGNvbmZpZyB9KSxcbiAgICBkZXZ0b29scygpLFxuICAgIHRhaWx3aW5kKCksXG4gICAgY29udGVudENvbGxlY3Rpb25zKHsgY29uZmlnUGF0aDogXCJjb250ZW50LWNvbGxlY3Rpb25zLnRzXCIgfSksXG4gICAgdGFuc3RhY2tTdGFydCh7XG4gICAgICBzcmNEaXJlY3Rvcnk6IFwiLlwiLFxuICAgICAgLy8gU2VlZCBwYXRoIG11c3QgbWF0Y2ggd2hhdCB0aGUgY3Jhd2xlciBwcm9kdWNlcyAocm91dGVyLWVtaXR0ZWRcbiAgICAgIC8vIGhyZWZzIGluY2x1ZGUgdGhlIGJhc2VwYXRoKSwgb3RoZXJ3aXNlIHByZXJlbmRlciByZWNvcmRzIGJvdGhcbiAgICAgIC8vIHNoYXBlcyBhbmQgdGhlIHNpdGVtYXAgZW5kcyB1cCB3aXRoIGR1cGxpY2F0ZSBlbnRyaWVzLlxuICAgICAgcGFnZXM6IFt7IHBhdGg6IGNvbmZpZy5iYXNlID8gYCR7Y29uZmlnLmJhc2V9L2AgOiBcIi9cIiB9XSxcbiAgICAgIC8vIERpc2FibGUgcm91dGUtdHJlZSBhdXRvLWRpc2NvdmVyeTogaXQgcHJvZHVjZXMgYmFzZXBhdGgtbmFpdmVcbiAgICAgIC8vIHBhdGhzIChlLmcuIGAvYCkgdGhhdCBkdXBsaWNhdGUgdGhlIGNyYXdsLWRlcml2ZWQgcHJlZml4ZWQgcGF0aHMsXG4gICAgICAvLyBibG9hdGluZyBwYWdlcy5qc29uIGFuZCBzaXRlbWFwLiBDcmF3bGluZyBmcm9tIHRoZSBzZWVkIGFscmVhZHlcbiAgICAgIC8vIHJlYWNoZXMgZXZlcnkgbGlua2VkIHBhZ2UuXG4gICAgICBwcmVyZW5kZXI6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgY3Jhd2xMaW5rczogdHJ1ZSxcbiAgICAgICAgYXV0b1N0YXRpY1BhdGhzRGlzY292ZXJ5OiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBzaXRlbWFwOiBjb25maWcuc2l0ZVxuICAgICAgICA/IHsgZW5hYmxlZDogdHJ1ZSwgaG9zdDogY29uZmlnLnNpdGUgfVxuICAgICAgICA6IHsgZW5hYmxlZDogZmFsc2UgfSxcbiAgICAgIHJvdXRlcjoge1xuICAgICAgICBnZW5lcmF0ZWRSb3V0ZVRyZWU6IFwicm91dGVUcmVlLmdlbi50c1wiLFxuICAgICAgICBiYXNlcGF0aDogY29uZmlnLmJhc2UsXG4gICAgICB9LFxuICAgIH0pLFxuICAgIHJlYWN0KCksXG4gICAgc3ZncigpLFxuICBdLFxufSlcbiJdfQ==
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidml0ZS5jb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zb3VyY2Uvdml0ZS5jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxrQkFBa0IsTUFBTSwyQkFBMkIsQ0FBQTtBQUMxRCxPQUFPLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUE7QUFDbEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFBO0FBQ2pFLE9BQU8sS0FBSyxNQUFNLHNCQUFzQixDQUFBO0FBQ3hDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUE7QUFDbkMsT0FBTyxJQUFJLE1BQU0sa0JBQWtCLENBQUE7QUFDbkMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFBO0FBQ3JELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQTtBQUNyRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sMEJBQTBCLENBQUE7QUFFakQsTUFBTSxNQUFNLEdBQUcsTUFBTSxVQUFVLEVBQUUsQ0FBQTtBQUVqQyx1RUFBdUU7QUFDdkUsd0VBQXdFO0FBQ3hFLHlFQUF5RTtBQUN6RSxtREFBbUQ7QUFDbkQsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLElBQUk7SUFDL0IsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7U0FDcEIsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUM7U0FDOUIsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNULElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxNQUFNLFNBQVM7UUFDOUMsT0FBTyxFQUFFLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRTtLQUMzQixDQUFDLENBQUM7SUFDUCxDQUFDLENBQUMsRUFBRSxDQUFBO0FBRU4sZUFBZSxZQUFZLENBQUM7SUFDMUIsT0FBTyxFQUFFO1FBQ1AsUUFBUSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDcEIsTUFBTSxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUM7UUFDbEIsUUFBUSxFQUFFO1FBQ1YsUUFBUSxFQUFFO1FBQ1Ysa0JBQWtCLENBQUMsRUFBRSxVQUFVLEVBQUUsd0JBQXdCLEVBQUUsQ0FBQztRQUM1RCxhQUFhLENBQUM7WUFDWixZQUFZLEVBQUUsR0FBRztZQUNqQixpRUFBaUU7WUFDakUsZ0VBQWdFO1lBQ2hFLHlEQUF5RDtZQUN6RCxLQUFLLEVBQUU7Z0JBQ0wsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRTtnQkFDL0MsR0FBRyxhQUFhO2FBQ2pCO1lBQ0QsZ0VBQWdFO1lBQ2hFLG9FQUFvRTtZQUNwRSxrRUFBa0U7WUFDbEUsNkJBQTZCO1lBQzdCLFNBQVMsRUFBRTtnQkFDVCxPQUFPLEVBQUUsSUFBSTtnQkFDYixVQUFVLEVBQUUsSUFBSTtnQkFDaEIsd0JBQXdCLEVBQUUsS0FBSzthQUNoQztZQUNELE9BQU8sRUFBRSxNQUFNLENBQUMsSUFBSTtnQkFDbEIsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRTtnQkFDdEMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRTtZQUN0QixNQUFNLEVBQUU7Z0JBQ04sa0JBQWtCLEVBQUUsa0JBQWtCO2dCQUN0QyxRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUk7YUFDdEI7U0FDRixDQUFDO1FBQ0YsS0FBSyxFQUFFO1FBQ1AsSUFBSSxFQUFFO0tBQ1A7Q0FDRixDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgY29udGVudENvbGxlY3Rpb25zIGZyb20gXCJAY29udGVudC1jb2xsZWN0aW9ucy92aXRlXCJcbmltcG9ydCB0YWlsd2luZCBmcm9tIFwiQHRhaWx3aW5kY3NzL3ZpdGVcIlxuaW1wb3J0IHsgZGV2dG9vbHMgfSBmcm9tIFwiQHRhbnN0YWNrL2RldnRvb2xzLXZpdGVcIlxuaW1wb3J0IHsgdGFuc3RhY2tTdGFydCB9IGZyb20gXCJAdGFuc3RhY2svcmVhY3Qtc3RhcnQvcGx1Z2luL3ZpdGVcIlxuaW1wb3J0IHJlYWN0IGZyb20gXCJAdml0ZWpzL3BsdWdpbi1yZWFjdFwiXG5pbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tIFwidml0ZVwiXG5pbXBvcnQgc3ZnciBmcm9tIFwidml0ZS1wbHVnaW4tc3ZnclwiXG5pbXBvcnQgeyBsb2FkQ29uZmlnIH0gZnJvbSBcIi4vYWN0aW9ucy9jb25maWcvbG9hZC50c1wiXG5pbXBvcnQgeyBsaXZlbWFyayB9IGZyb20gXCIuL3BsdWdpbnMvdml0ZS1saXZlbWFyay50c1wiXG5pbXBvcnQgeyByb2JvdHMgfSBmcm9tIFwiLi9wbHVnaW5zL3ZpdGUtcm9ib3RzLnRzXCJcblxuY29uc3QgY29uZmlnID0gYXdhaXQgbG9hZENvbmZpZygpXG5cbi8vIFBlci1ibG9nLXNlY3Rpb24gUlNTIGZlZWQgcGF0aHMgdG8gcHJlcmVuZGVyLiBHYXRlZCBvbiBgY29uZmlnLnNpdGVgXG4vLyBiZWNhdXNlIGZlZWQgVVJMcyBhcmUgYWJzb2x1dGUgKG1hdGNoaW5nIHRoZSBzaXRlbWFwL3JvYm90cy50eHQgZ2F0ZSlcbi8vIGFuZCB0aGUgcm91dGUgcmV0dXJucyA0MDQgd2l0aG91dCBpdCBhbnl3YXkuIEV4Y2x1ZGVkIGZyb20gdGhlIHNpdGVtYXBcbi8vIHNpbmNlIGAueG1sYCBwYXlsb2FkcyBkb24ndCBiZWxvbmcgaW4gYSBzaXRlbWFwLlxuY29uc3QgYmxvZ0ZlZWRQYWdlcyA9IGNvbmZpZy5zaXRlXG4gID8gKGNvbmZpZy5zZWN0aW9ucyA/PyBbXSlcbiAgICAgIC5maWx0ZXIocyA9PiBzLnR5cGUgPT09IFwiYmxvZ1wiKVxuICAgICAgLm1hcChzID0+ICh7XG4gICAgICAgIHBhdGg6IGAke2NvbmZpZy5iYXNlID8/IFwiXCJ9JHtzLnByZWZpeH1yc3MueG1sYCxcbiAgICAgICAgc2l0ZW1hcDogeyBleGNsdWRlOiB0cnVlIH0sXG4gICAgICB9KSlcbiAgOiBbXVxuXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoe1xuICBwbHVnaW5zOiBbXG4gICAgbGl2ZW1hcmsoeyBjb25maWcgfSksXG4gICAgcm9ib3RzKHsgY29uZmlnIH0pLFxuICAgIGRldnRvb2xzKCksXG4gICAgdGFpbHdpbmQoKSxcbiAgICBjb250ZW50Q29sbGVjdGlvbnMoeyBjb25maWdQYXRoOiBcImNvbnRlbnQtY29sbGVjdGlvbnMudHNcIiB9KSxcbiAgICB0YW5zdGFja1N0YXJ0KHtcbiAgICAgIHNyY0RpcmVjdG9yeTogXCIuXCIsXG4gICAgICAvLyBTZWVkIHBhdGggbXVzdCBtYXRjaCB3aGF0IHRoZSBjcmF3bGVyIHByb2R1Y2VzIChyb3V0ZXItZW1pdHRlZFxuICAgICAgLy8gaHJlZnMgaW5jbHVkZSB0aGUgYmFzZXBhdGgpLCBvdGhlcndpc2UgcHJlcmVuZGVyIHJlY29yZHMgYm90aFxuICAgICAgLy8gc2hhcGVzIGFuZCB0aGUgc2l0ZW1hcCBlbmRzIHVwIHdpdGggZHVwbGljYXRlIGVudHJpZXMuXG4gICAgICBwYWdlczogW1xuICAgICAgICB7IHBhdGg6IGNvbmZpZy5iYXNlID8gYCR7Y29uZmlnLmJhc2V9L2AgOiBcIi9cIiB9LFxuICAgICAgICAuLi5ibG9nRmVlZFBhZ2VzLFxuICAgICAgXSxcbiAgICAgIC8vIERpc2FibGUgcm91dGUtdHJlZSBhdXRvLWRpc2NvdmVyeTogaXQgcHJvZHVjZXMgYmFzZXBhdGgtbmFpdmVcbiAgICAgIC8vIHBhdGhzIChlLmcuIGAvYCkgdGhhdCBkdXBsaWNhdGUgdGhlIGNyYXdsLWRlcml2ZWQgcHJlZml4ZWQgcGF0aHMsXG4gICAgICAvLyBibG9hdGluZyBwYWdlcy5qc29uIGFuZCBzaXRlbWFwLiBDcmF3bGluZyBmcm9tIHRoZSBzZWVkIGFscmVhZHlcbiAgICAgIC8vIHJlYWNoZXMgZXZlcnkgbGlua2VkIHBhZ2UuXG4gICAgICBwcmVyZW5kZXI6IHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgY3Jhd2xMaW5rczogdHJ1ZSxcbiAgICAgICAgYXV0b1N0YXRpY1BhdGhzRGlzY292ZXJ5OiBmYWxzZSxcbiAgICAgIH0sXG4gICAgICBzaXRlbWFwOiBjb25maWcuc2l0ZVxuICAgICAgICA/IHsgZW5hYmxlZDogdHJ1ZSwgaG9zdDogY29uZmlnLnNpdGUgfVxuICAgICAgICA6IHsgZW5hYmxlZDogZmFsc2UgfSxcbiAgICAgIHJvdXRlcjoge1xuICAgICAgICBnZW5lcmF0ZWRSb3V0ZVRyZWU6IFwicm91dGVUcmVlLmdlbi50c1wiLFxuICAgICAgICBiYXNlcGF0aDogY29uZmlnLmJhc2UsXG4gICAgICB9LFxuICAgIH0pLFxuICAgIHJlYWN0KCksXG4gICAgc3ZncigpLFxuICBdLFxufSlcbiJdfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "livemark",
3
- "version": "0.21.0",
3
+ "version": "0.23.0",
4
4
  "description": "Livemark description",
5
5
  "license": "MIT",
6
6
  "author": "Evgeny Karev",
@@ -92,6 +92,6 @@ After authoring, run:
92
92
 
93
93
  ## References
94
94
 
95
- - Full frontmatter reference: `docs/markdown/frontmatter.md`.
95
+ - Full frontmatter reference: `docs/authoring/frontmatter.md`.
96
96
  - Schema source of truth: `website/models/article.ts`.
97
97
  - Transform pipeline: `website/content-collections.ts`.
@@ -1,6 +1,8 @@
1
1
  import { useState, useCallback } from "react"
2
2
  import { Eye, Pencil, Copy, Check, ExternalLink } from "lucide-react"
3
3
 
4
+ const LLM_PROMPT = "Read {url}, I want to ask questions about it."
5
+
4
6
  /** Toolbar with action buttons displayed for the article content */
5
7
  export function PageToolbar(props: {
6
8
  file?: string
@@ -24,13 +26,11 @@ export function PageToolbar(props: {
24
26
  setTimeout(() => setCopied(false), 2000)
25
27
  }, [props.content])
26
28
 
27
- const handleOpenIn = useCallback(
28
- (url: string) => {
29
- navigator.clipboard.writeText(props.content)
30
- window.open(url, "_blank", "noopener,noreferrer")
31
- },
32
- [props.content],
33
- )
29
+ const openIn = (base: string, extra?: Record<string, string>) => {
30
+ const q = LLM_PROMPT.replace("{url}", window.location.href)
31
+ const params = new URLSearchParams({ ...extra, q })
32
+ window.open(`${base}?${params}`, "_blank", "noopener,noreferrer")
33
+ }
34
34
 
35
35
  const buttonClass =
36
36
  "flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition-colors"
@@ -68,7 +68,7 @@ export function PageToolbar(props: {
68
68
  </button>
69
69
  <button
70
70
  type="button"
71
- onClick={() => handleOpenIn("https://chatgpt.com/")}
71
+ onClick={() => openIn("https://chatgpt.com/", { hints: "search" })}
72
72
  className={buttonClass}
73
73
  >
74
74
  <ExternalLink className="size-3.5" />
@@ -76,7 +76,7 @@ export function PageToolbar(props: {
76
76
  </button>
77
77
  <button
78
78
  type="button"
79
- onClick={() => handleOpenIn("https://claude.ai/")}
79
+ onClick={() => openIn("https://claude.ai/new")}
80
80
  className={buttonClass}
81
81
  >
82
82
  <ExternalLink className="size-3.5" />
@@ -1,3 +1,4 @@
1
+ import { config } from "livemark:virtual"
1
2
  import { Link, useLocation } from "@tanstack/react-router"
2
3
  import { Clock, List, Rss, Tag } from "lucide-react"
3
4
  import {
@@ -87,12 +88,17 @@ export function SidebarPosts() {
87
88
  })}
88
89
  </SidebarMenuSub>
89
90
  </SidebarMenuItem>
90
- <SidebarMenuItem>
91
- <SidebarMenuButton className="opacity-75">
92
- <Rss className="size-4" />
93
- <span>RSS Feed</span>
94
- </SidebarMenuButton>
95
- </SidebarMenuItem>
91
+ {config.site && (
92
+ <SidebarMenuItem>
93
+ <SidebarMenuButton
94
+ className="opacity-75"
95
+ render={<a href={`/${sectionPath}/rss.xml`} />}
96
+ >
97
+ <Rss className="size-4" />
98
+ <span>RSS Feed</span>
99
+ </SidebarMenuButton>
100
+ </SidebarMenuItem>
101
+ )}
96
102
  </SidebarMenu>
97
103
  </SidebarGroupContent>
98
104
  </SidebarGroup>
@@ -0,0 +1,80 @@
1
+ export interface RssItem {
2
+ title: string
3
+ link: string
4
+ guid: string
5
+ description?: string
6
+ pubDate?: string
7
+ author?: string | string[]
8
+ categories?: string[]
9
+ }
10
+
11
+ export interface RssFeed {
12
+ title: string
13
+ description: string
14
+ link: string
15
+ feedLink: string
16
+ items: RssItem[]
17
+ }
18
+
19
+ /** Render an RSS 2.0 channel as a serialized XML document. Pure — all I/O,
20
+ * URL composition, and item-count limits live in the caller. `pubDate` is
21
+ * accepted as an ISO string (article frontmatter shape) and converted to
22
+ * RFC 822 here, which is what readers like NetNewsWire and Feedly parse. */
23
+ export function renderRssFeed(feed: RssFeed) {
24
+ const lines: string[] = []
25
+ lines.push('<?xml version="1.0" encoding="UTF-8"?>')
26
+ lines.push('<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">')
27
+ lines.push(" <channel>")
28
+ lines.push(` <title>${escapeXml(feed.title)}</title>`)
29
+ lines.push(` <link>${escapeXml(feed.link)}</link>`)
30
+ lines.push(` <description>${escapeXml(feed.description)}</description>`)
31
+ lines.push(
32
+ ` <atom:link href="${escapeXml(feed.feedLink)}" rel="self" type="application/rss+xml" />`,
33
+ )
34
+ for (const item of feed.items) {
35
+ lines.push(" <item>")
36
+ lines.push(` <title>${escapeXml(item.title)}</title>`)
37
+ lines.push(` <link>${escapeXml(item.link)}</link>`)
38
+ lines.push(` <guid isPermaLink="true">${escapeXml(item.guid)}</guid>`)
39
+ if (item.description) {
40
+ lines.push(
41
+ ` <description>${escapeXml(item.description)}</description>`,
42
+ )
43
+ }
44
+ if (item.pubDate) {
45
+ lines.push(
46
+ ` <pubDate>${escapeXml(toRfc822(item.pubDate))}</pubDate>`,
47
+ )
48
+ }
49
+ if (item.author) {
50
+ const author = Array.isArray(item.author)
51
+ ? item.author.join(", ")
52
+ : item.author
53
+ lines.push(` <author>${escapeXml(author)}</author>`)
54
+ }
55
+ if (item.categories) {
56
+ for (const category of item.categories) {
57
+ lines.push(` <category>${escapeXml(category)}</category>`)
58
+ }
59
+ }
60
+ lines.push(" </item>")
61
+ }
62
+ lines.push(" </channel>")
63
+ lines.push("</rss>")
64
+ return `${lines.join("\n")}\n`
65
+ }
66
+
67
+ function escapeXml(value: string) {
68
+ return value
69
+ .replace(/&/g, "&amp;")
70
+ .replace(/</g, "&lt;")
71
+ .replace(/>/g, "&gt;")
72
+ .replace(/"/g, "&quot;")
73
+ .replace(/'/g, "&apos;")
74
+ }
75
+
76
+ function toRfc822(iso: string) {
77
+ const date = new Date(iso)
78
+ if (Number.isNaN(date.getTime())) return iso
79
+ return date.toUTCString()
80
+ }
@@ -0,0 +1,134 @@
1
+ import { describe, expect, it } from "vite-plus/test"
2
+ import { renderRssFeed } from "./rss.ts"
3
+
4
+ describe("renderRssFeed", () => {
5
+ it("renders a minimal channel with no items", () => {
6
+ const xml = renderRssFeed({
7
+ title: "Blog",
8
+ description: "Latest posts",
9
+ link: "https://example.com/blog/",
10
+ feedLink: "https://example.com/blog/rss.xml",
11
+ items: [],
12
+ })
13
+ expect(xml).toBe(
14
+ `<?xml version="1.0" encoding="UTF-8"?>
15
+ <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
16
+ <channel>
17
+ <title>Blog</title>
18
+ <link>https://example.com/blog/</link>
19
+ <description>Latest posts</description>
20
+ <atom:link href="https://example.com/blog/rss.xml" rel="self" type="application/rss+xml" />
21
+ </channel>
22
+ </rss>
23
+ `,
24
+ )
25
+ })
26
+
27
+ it("renders an item with all optional fields", () => {
28
+ const xml = renderRssFeed({
29
+ title: "Blog",
30
+ description: "Latest posts",
31
+ link: "https://example.com/blog/",
32
+ feedLink: "https://example.com/blog/rss.xml",
33
+ items: [
34
+ {
35
+ title: "Hello",
36
+ link: "https://example.com/blog/hello/",
37
+ guid: "https://example.com/blog/hello/",
38
+ description: "First post",
39
+ pubDate: "2026-05-16T00:00:00Z",
40
+ author: "Jane",
41
+ categories: ["news"],
42
+ },
43
+ ],
44
+ })
45
+ expect(xml).toContain("<title>Hello</title>")
46
+ expect(xml).toContain("<link>https://example.com/blog/hello/</link>")
47
+ expect(xml).toContain(
48
+ '<guid isPermaLink="true">https://example.com/blog/hello/</guid>',
49
+ )
50
+ expect(xml).toContain("<description>First post</description>")
51
+ expect(xml).toContain("<pubDate>Sat, 16 May 2026 00:00:00 GMT</pubDate>")
52
+ expect(xml).toContain("<author>Jane</author>")
53
+ expect(xml).toContain("<category>news</category>")
54
+ })
55
+
56
+ it("joins array authors with a comma", () => {
57
+ const xml = renderRssFeed({
58
+ title: "Blog",
59
+ description: "",
60
+ link: "https://example.com/blog/",
61
+ feedLink: "https://example.com/blog/rss.xml",
62
+ items: [
63
+ {
64
+ title: "x",
65
+ link: "https://example.com/blog/x/",
66
+ guid: "https://example.com/blog/x/",
67
+ author: ["Alice", "Bob"],
68
+ },
69
+ ],
70
+ })
71
+ expect(xml).toContain("<author>Alice, Bob</author>")
72
+ })
73
+
74
+ it("emits one <category> per tag", () => {
75
+ const xml = renderRssFeed({
76
+ title: "Blog",
77
+ description: "",
78
+ link: "https://example.com/blog/",
79
+ feedLink: "https://example.com/blog/rss.xml",
80
+ items: [
81
+ {
82
+ title: "x",
83
+ link: "https://example.com/blog/x/",
84
+ guid: "https://example.com/blog/x/",
85
+ categories: ["a", "b", "c"],
86
+ },
87
+ ],
88
+ })
89
+ expect(xml).toContain("<category>a</category>")
90
+ expect(xml).toContain("<category>b</category>")
91
+ expect(xml).toContain("<category>c</category>")
92
+ })
93
+
94
+ it("escapes XML metacharacters in text content", () => {
95
+ const xml = renderRssFeed({
96
+ title: 'Title & "quoted" <tag>',
97
+ description: "A & B",
98
+ link: "https://example.com/blog/",
99
+ feedLink: "https://example.com/blog/rss.xml",
100
+ items: [
101
+ {
102
+ title: "1 < 2 & 3 > 0",
103
+ link: "https://example.com/blog/x/",
104
+ guid: "https://example.com/blog/x/",
105
+ description: "It's fine",
106
+ },
107
+ ],
108
+ })
109
+ expect(xml).toContain(
110
+ "<title>Title &amp; &quot;quoted&quot; &lt;tag&gt;</title>",
111
+ )
112
+ expect(xml).toContain("<description>A &amp; B</description>")
113
+ expect(xml).toContain("<title>1 &lt; 2 &amp; 3 &gt; 0</title>")
114
+ expect(xml).toContain("<description>It&apos;s fine</description>")
115
+ })
116
+
117
+ it("leaves an unparsable pubDate unchanged", () => {
118
+ const xml = renderRssFeed({
119
+ title: "Blog",
120
+ description: "",
121
+ link: "https://example.com/blog/",
122
+ feedLink: "https://example.com/blog/rss.xml",
123
+ items: [
124
+ {
125
+ title: "x",
126
+ link: "https://example.com/blog/x/",
127
+ guid: "https://example.com/blog/x/",
128
+ pubDate: "not-a-date",
129
+ },
130
+ ],
131
+ })
132
+ expect(xml).toContain("<pubDate>not-a-date</pubDate>")
133
+ })
134
+ })
@@ -10,6 +10,7 @@
10
10
 
11
11
  import { Route as rootRouteImport } from './routes/__root'
12
12
  import { Route as splatRouteImport } from './routes/$'
13
+ import { Route as SectionRssDotxmlRouteImport } from './routes/$section.rss[.]xml'
13
14
  import { Route as IndexRouteImport } from './../.livemark/routes/index'
14
15
 
15
16
  const splatRoute = splatRouteImport.update({
@@ -17,6 +18,11 @@ const splatRoute = splatRouteImport.update({
17
18
  path: '/$',
18
19
  getParentRoute: () => rootRouteImport,
19
20
  } as any)
21
+ const SectionRssDotxmlRoute = SectionRssDotxmlRouteImport.update({
22
+ id: '/$section/rss.xml',
23
+ path: '/$section/rss.xml',
24
+ getParentRoute: () => rootRouteImport,
25
+ } as any)
20
26
  const IndexRoute = IndexRouteImport.update({
21
27
  id: '/',
22
28
  path: '/',
@@ -26,27 +32,31 @@ const IndexRoute = IndexRouteImport.update({
26
32
  export interface FileRoutesByFullPath {
27
33
  '/': typeof IndexRoute
28
34
  '/$': typeof splatRoute
35
+ '/$section/rss.xml': typeof SectionRssDotxmlRoute
29
36
  }
30
37
  export interface FileRoutesByTo {
31
38
  '/': typeof IndexRoute
32
39
  '/$': typeof splatRoute
40
+ '/$section/rss.xml': typeof SectionRssDotxmlRoute
33
41
  }
34
42
  export interface FileRoutesById {
35
43
  __root__: typeof rootRouteImport
36
44
  '/': typeof IndexRoute
37
45
  '/$': typeof splatRoute
46
+ '/$section/rss.xml': typeof SectionRssDotxmlRoute
38
47
  }
39
48
  export interface FileRouteTypes {
40
49
  fileRoutesByFullPath: FileRoutesByFullPath
41
- fullPaths: '/' | '/$'
50
+ fullPaths: '/' | '/$' | '/$section/rss.xml'
42
51
  fileRoutesByTo: FileRoutesByTo
43
- to: '/' | '/$'
44
- id: '__root__' | '/' | '/$'
52
+ to: '/' | '/$' | '/$section/rss.xml'
53
+ id: '__root__' | '/' | '/$' | '/$section/rss.xml'
45
54
  fileRoutesById: FileRoutesById
46
55
  }
47
56
  export interface RootRouteChildren {
48
57
  IndexRoute: typeof IndexRoute
49
58
  splatRoute: typeof splatRoute
59
+ SectionRssDotxmlRoute: typeof SectionRssDotxmlRoute
50
60
  }
51
61
 
52
62
  declare module '@tanstack/react-router' {
@@ -58,6 +68,13 @@ declare module '@tanstack/react-router' {
58
68
  preLoaderRoute: typeof splatRouteImport
59
69
  parentRoute: typeof rootRouteImport
60
70
  }
71
+ '/$section/rss.xml': {
72
+ id: '/$section/rss.xml'
73
+ path: '/$section/rss.xml'
74
+ fullPath: '/$section/rss.xml'
75
+ preLoaderRoute: typeof SectionRssDotxmlRouteImport
76
+ parentRoute: typeof rootRouteImport
77
+ }
61
78
  '/': {
62
79
  id: '/'
63
80
  path: '/'
@@ -71,6 +88,7 @@ declare module '@tanstack/react-router' {
71
88
  const rootRouteChildren: RootRouteChildren = {
72
89
  IndexRoute: IndexRoute,
73
90
  splatRoute: splatRoute,
91
+ SectionRssDotxmlRoute: SectionRssDotxmlRoute,
74
92
  }
75
93
  export const routeTree = rootRouteImport
76
94
  ._addFileChildren(rootRouteChildren)
@@ -0,0 +1,60 @@
1
+ import { config } from "livemark:virtual"
2
+ import { createFileRoute } from "@tanstack/react-router"
3
+ import { sectionFlatArticles, sortedArticles } from "../content/article.ts"
4
+ import { renderRssFeed, type RssItem } from "../helpers/rss.ts"
5
+
6
+ const FEED_ITEM_LIMIT = 20
7
+
8
+ export const Route = createFileRoute("/$section/rss.xml")({
9
+ server: {
10
+ handlers: {
11
+ GET: async ({ params }: { params: { section: string } }) => {
12
+ if (!config.site) {
13
+ return new Response("RSS requires `site` in livemark.config.ts", {
14
+ status: 404,
15
+ })
16
+ }
17
+ const prefix = `/${params.section}/`
18
+ const section = config.sections?.find(
19
+ s => s.type === "blog" && s.prefix === prefix,
20
+ )
21
+ if (!section || section.type !== "blog") {
22
+ return new Response("Not found", { status: 404 })
23
+ }
24
+ const host = config.site.replace(/\/+$/, "")
25
+ const base = config.base ?? ""
26
+ const toAbsolute = (path: string) => `${host}${base}${path}`
27
+
28
+ const paths = sectionFlatArticles.get(section.prefix) ?? []
29
+ const items: RssItem[] = []
30
+ for (const path of paths) {
31
+ if (items.length >= FEED_ITEM_LIMIT) break
32
+ const article = sortedArticles.find(a => a.path === path)
33
+ if (!article?.date) continue
34
+ const link = toAbsolute(article.path)
35
+ items.push({
36
+ title: article.title,
37
+ link,
38
+ guid: link,
39
+ description: article.description,
40
+ pubDate: article.date,
41
+ author: article.author,
42
+ categories: article.tags,
43
+ })
44
+ }
45
+
46
+ const xml = renderRssFeed({
47
+ title: section.siteTitle ?? section.title,
48
+ description: section.siteDescription ?? config.description ?? "",
49
+ link: toAbsolute(section.prefix),
50
+ feedLink: toAbsolute(`${section.prefix}rss.xml`),
51
+ items,
52
+ })
53
+
54
+ return new Response(xml, {
55
+ headers: { "Content-Type": "application/rss+xml; charset=utf-8" },
56
+ })
57
+ },
58
+ },
59
+ },
60
+ })
@@ -26,6 +26,16 @@ export const Route = createRootRoute({
26
26
  config.favicon ?? config.logo ?? defaultFavicon,
27
27
  config.base,
28
28
  )
29
+ const feedLinks = config.site
30
+ ? (config.sections ?? [])
31
+ .filter(s => s.type === "blog")
32
+ .map(s => ({
33
+ rel: "alternate",
34
+ type: "application/rss+xml",
35
+ title: `${s.siteTitle ?? s.title} RSS Feed`,
36
+ href: prefixUrl(`${s.prefix}rss.xml`, config.base),
37
+ }))
38
+ : []
29
39
  return {
30
40
  meta: [
31
41
  { charSet: "utf-8" },
@@ -48,6 +58,7 @@ export const Route = createRootRoute({
48
58
  { rel: "shortcut icon", href: favicon, type: faviconType(favicon) },
49
59
  { rel: "stylesheet", href: generalCss },
50
60
  { rel: "stylesheet", href: markdownCss },
61
+ ...feedLinks,
51
62
  ],
52
63
  }
53
64
  },
@@ -11,6 +11,19 @@ import { robots } from "./plugins/vite-robots.ts"
11
11
 
12
12
  const config = await loadConfig()
13
13
 
14
+ // Per-blog-section RSS feed paths to prerender. Gated on `config.site`
15
+ // because feed URLs are absolute (matching the sitemap/robots.txt gate)
16
+ // and the route returns 404 without it anyway. Excluded from the sitemap
17
+ // since `.xml` payloads don't belong in a sitemap.
18
+ const blogFeedPages = config.site
19
+ ? (config.sections ?? [])
20
+ .filter(s => s.type === "blog")
21
+ .map(s => ({
22
+ path: `${config.base ?? ""}${s.prefix}rss.xml`,
23
+ sitemap: { exclude: true },
24
+ }))
25
+ : []
26
+
14
27
  export default defineConfig({
15
28
  plugins: [
16
29
  livemark({ config }),
@@ -23,7 +36,10 @@ export default defineConfig({
23
36
  // Seed path must match what the crawler produces (router-emitted
24
37
  // hrefs include the basepath), otherwise prerender records both
25
38
  // shapes and the sitemap ends up with duplicate entries.
26
- pages: [{ path: config.base ? `${config.base}/` : "/" }],
39
+ pages: [
40
+ { path: config.base ? `${config.base}/` : "/" },
41
+ ...blogFeedPages,
42
+ ],
27
43
  // Disable route-tree auto-discovery: it produces basepath-naive
28
44
  // paths (e.g. `/`) that duplicate the crawl-derived prefixed paths,
29
45
  // bloating pages.json and sitemap. Crawling from the seed already