@quark.clip/quark 1.0.0 → 1.1.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 +20 -11
- package/cli/package.json +1 -1
- package/cli/src/clipboard.js +13 -5
- package/cli/src/daemon.js +50 -8
- package/cli/src/transformers.js +33 -15
- package/dist/assets/{index-CaferGuT.js → index-CDMgweEY.js} +3 -3
- package/dist/index.html +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="public/logo.svg" width="80" alt="Quark Logo" />
|
|
3
|
+
|
|
4
|
+
# 🌌 Quark
|
|
5
|
+
|
|
6
|
+
### The AI-Native, Cross-Platform Clipboard Micro-Daemon.
|
|
7
|
+
|
|
8
|
+
[](https://www.npmjs.com/package/@quark.clip/quark)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
[](https://github.com/sir-ad/quark/stargazers)
|
|
11
|
+
[](https://modelcontextprotocol.io)
|
|
12
|
+
|
|
13
|
+
Quark is a headless, zero-configuration background service that orbits your operating system's clipboard. It silently fixes your copy-paste nightmares, syncs your clipboard across devices seamlessly, and exposes your clipboard directly to local AI models.
|
|
14
|
+
</div>
|
|
8
15
|
|
|
9
16
|
---
|
|
10
17
|
|
|
@@ -34,10 +41,10 @@ No `.exe` files. No `.dmg` files. Just pure, cross-platform JavaScript.
|
|
|
34
41
|
|
|
35
42
|
```bash
|
|
36
43
|
# Run instantly without installing (Temporary Session)
|
|
37
|
-
npx
|
|
44
|
+
npx -y @quark.clip/quark start
|
|
38
45
|
|
|
39
46
|
# OR install globally as a background OS service
|
|
40
|
-
npm install -g quark
|
|
47
|
+
npm install -g @quark.clip/quark
|
|
41
48
|
quark install
|
|
42
49
|
```
|
|
43
50
|
|
|
@@ -104,7 +111,7 @@ To give Claude Desktop access to your clipboard, add Quark to your `claude_deskt
|
|
|
104
111
|
"mcpServers": {
|
|
105
112
|
"quark": {
|
|
106
113
|
"command": "npx",
|
|
107
|
-
"args": ["
|
|
114
|
+
"args": ["-y", "@quark.clip/quark", "mcp"]
|
|
108
115
|
}
|
|
109
116
|
}
|
|
110
117
|
}
|
|
@@ -119,4 +126,6 @@ Please read `CONTRIBUTING.md` for details on our code of conduct, and the proces
|
|
|
119
126
|
|
|
120
127
|
## 📄 License
|
|
121
128
|
|
|
122
|
-
This project is licensed under the MIT License - see the
|
|
129
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
130
|
+
|
|
131
|
+
© 2026 Adarsh Agrahari. All Rights Reserved.
|
package/cli/package.json
CHANGED
package/cli/src/clipboard.js
CHANGED
|
@@ -12,12 +12,12 @@ function read() {
|
|
|
12
12
|
const hex = execSync(`osascript -e 'the clipboard as "HTML"' 2>/dev/null`, { encoding: 'utf8' });
|
|
13
13
|
const match = hex.match(/«data HTML([0-9A-F]+)»/i);
|
|
14
14
|
if (match) html = Buffer.from(match[1], 'hex').toString('utf8');
|
|
15
|
-
} catch(e) {}
|
|
15
|
+
} catch (e) { }
|
|
16
16
|
} else if (platform === 'linux') {
|
|
17
17
|
text = execSync('xclip -selection clipboard -o', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).toString();
|
|
18
18
|
try {
|
|
19
19
|
html = execSync('xclip -selection clipboard -o -t text/html', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).toString();
|
|
20
|
-
} catch(e) {}
|
|
20
|
+
} catch (e) { }
|
|
21
21
|
} else if (platform === 'win32') {
|
|
22
22
|
text = execSync('powershell -NoProfile -Command "Get-Clipboard -Format Text"', { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).toString().replace(/\r\n$/, '');
|
|
23
23
|
try {
|
|
@@ -29,7 +29,7 @@ function read() {
|
|
|
29
29
|
} else {
|
|
30
30
|
html = rawHtml.replace(/^Version:.*?\r?\nStartHTML:.*?\r?\nEndHTML:.*?\r?\nStartFragment:.*?\r?\nEndFragment:.*?\r?\n/is, '');
|
|
31
31
|
}
|
|
32
|
-
} catch(e) {}
|
|
32
|
+
} catch (e) { }
|
|
33
33
|
}
|
|
34
34
|
} catch (e) {
|
|
35
35
|
return { text: '', html: '' };
|
|
@@ -41,8 +41,16 @@ function writeHtml(html, plainText) {
|
|
|
41
41
|
try {
|
|
42
42
|
const platform = os.platform();
|
|
43
43
|
if (platform === 'darwin') {
|
|
44
|
-
//
|
|
45
|
-
|
|
44
|
+
// Use hex-encoded AppleScript to set both HTML and Plain Text flavors simultaneously.
|
|
45
|
+
// This is the only way to ensure Electron apps (Teams/Slack) recognize the grid layout.
|
|
46
|
+
const hexHtml = Buffer.from(html, 'utf8').toString('hex').toUpperCase();
|
|
47
|
+
const hexText = Buffer.from(plainText, 'utf8').toString('hex').toUpperCase();
|
|
48
|
+
|
|
49
|
+
const script = `
|
|
50
|
+
set the clipboard to { «class HTML»: «data HTML${hexHtml}», Unicode text: (run script "«data utxt${hexText}»") }
|
|
51
|
+
`;
|
|
52
|
+
|
|
53
|
+
execSync(`osascript -e '${script.replace(/\n/g, ' ')}'`);
|
|
46
54
|
} else if (platform === 'linux') {
|
|
47
55
|
execSync('xclip -selection clipboard -t text/html', { input: html, stdio: ['pipe', 'ignore', 'ignore'] });
|
|
48
56
|
} else if (platform === 'win32') {
|
package/cli/src/daemon.js
CHANGED
|
@@ -24,6 +24,25 @@ network.init((remoteData) => {
|
|
|
24
24
|
// Local HTTP Server for MCP Bridge
|
|
25
25
|
// The MCP stdio process will call this to read/write clipboard
|
|
26
26
|
const API_PORT = 14314;
|
|
27
|
+
|
|
28
|
+
function logEvent(type, message, metadata = {}) {
|
|
29
|
+
const ts = new Date().toISOString().replace(/T/, ' ').replace(/\..+/, '');
|
|
30
|
+
const icon = {
|
|
31
|
+
CLIP: '📋',
|
|
32
|
+
TRANSFORM: '✨',
|
|
33
|
+
SYNC: '📡',
|
|
34
|
+
INFO: '💡',
|
|
35
|
+
WARN: '⚠️'
|
|
36
|
+
}[type] || '⚪';
|
|
37
|
+
|
|
38
|
+
console.log(`[${ts}] ${icon} ${type}: ${message}`);
|
|
39
|
+
if (Object.keys(metadata).length > 0) {
|
|
40
|
+
console.log(` ${JSON.stringify(metadata)}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let writeGuard = false;
|
|
45
|
+
|
|
27
46
|
const server = http.createServer((req, res) => {
|
|
28
47
|
if (req.url === '/clipboard' && req.method === 'GET') {
|
|
29
48
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
@@ -35,6 +54,8 @@ const server = http.createServer((req, res) => {
|
|
|
35
54
|
try {
|
|
36
55
|
const data = JSON.parse(body);
|
|
37
56
|
if (data.text) {
|
|
57
|
+
logEvent('INFO', 'Writing to clipboard via MCP');
|
|
58
|
+
writeGuard = true;
|
|
38
59
|
clipboard.writeText(data.text);
|
|
39
60
|
lastClip = clipboard.read();
|
|
40
61
|
network.broadcast(data.text);
|
|
@@ -51,23 +72,41 @@ const server = http.createServer((req, res) => {
|
|
|
51
72
|
res.end();
|
|
52
73
|
}
|
|
53
74
|
});
|
|
75
|
+
|
|
54
76
|
server.listen(API_PORT, '127.0.0.1', () => {
|
|
55
|
-
|
|
77
|
+
logEvent('INFO', `Local API for MCP Bridge listening on port ${API_PORT}`);
|
|
56
78
|
});
|
|
57
79
|
|
|
58
80
|
// Main Clipboard Polling Loop
|
|
59
81
|
const pollInterval = setInterval(async () => {
|
|
60
|
-
if (isSyncingFromNetwork) return;
|
|
82
|
+
if (isSyncingFromNetwork) return;
|
|
61
83
|
|
|
62
84
|
const currentClip = clipboard.read();
|
|
85
|
+
|
|
86
|
+
// Self-Write Guard: Check if this change was triggered by our own write
|
|
87
|
+
if (writeGuard) {
|
|
88
|
+
if (currentClip.text === lastClip.text && currentClip.html === lastClip.html) {
|
|
89
|
+
writeGuard = false; // Reset guard after confirming parity
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
// If it's different, maybe the OS modified it or user copied something else simultaneously
|
|
93
|
+
writeGuard = false;
|
|
94
|
+
}
|
|
95
|
+
|
|
63
96
|
if (currentClip.text && (currentClip.text !== lastClip.text || currentClip.html !== lastClip.html)) {
|
|
64
97
|
lastClip = currentClip;
|
|
65
|
-
|
|
98
|
+
|
|
99
|
+
logEvent('CLIP', 'New content detected', {
|
|
100
|
+
textLength: currentClip.text.length,
|
|
101
|
+
hasHtml: !!currentClip.html
|
|
102
|
+
});
|
|
103
|
+
|
|
66
104
|
// Process through transformers
|
|
67
105
|
const result = await transformers.processClipboard(currentClip.text, currentClip.html);
|
|
68
|
-
|
|
106
|
+
|
|
69
107
|
if (result.changed) {
|
|
70
|
-
|
|
108
|
+
logEvent('TRANSFORM', result.skipReason || 'Applying transformations');
|
|
109
|
+
writeGuard = true;
|
|
71
110
|
if (result.html) {
|
|
72
111
|
clipboard.writeHtml(result.html, result.text);
|
|
73
112
|
} else {
|
|
@@ -76,6 +115,9 @@ const pollInterval = setInterval(async () => {
|
|
|
76
115
|
lastClip = clipboard.read(); // Update to OS state
|
|
77
116
|
network.broadcast(result.text, result.html);
|
|
78
117
|
} else {
|
|
118
|
+
if (result.skipReason) {
|
|
119
|
+
logEvent('INFO', `Skipped: ${result.skipReason}`);
|
|
120
|
+
}
|
|
79
121
|
// No transformation, just broadcast raw text and html to peers
|
|
80
122
|
network.broadcast(currentClip.text, currentClip.html);
|
|
81
123
|
}
|
|
@@ -84,13 +126,13 @@ const pollInterval = setInterval(async () => {
|
|
|
84
126
|
|
|
85
127
|
// Graceful Shutdown
|
|
86
128
|
function shutdown() {
|
|
87
|
-
|
|
129
|
+
logEvent('INFO', 'Shutting down Quark Daemon gracefully...');
|
|
88
130
|
clearInterval(pollInterval);
|
|
89
131
|
server.close(() => {
|
|
90
|
-
|
|
132
|
+
logEvent('INFO', 'MCP Bridge API closed.');
|
|
91
133
|
process.exit(0);
|
|
92
134
|
});
|
|
93
|
-
|
|
135
|
+
|
|
94
136
|
// Force exit if server takes too long
|
|
95
137
|
setTimeout(() => {
|
|
96
138
|
console.error('⚠️ Forced shutdown due to timeout.');
|
package/cli/src/transformers.js
CHANGED
|
@@ -66,21 +66,21 @@ function applySmartQuotes(text) {
|
|
|
66
66
|
const frenchChars = (text.match(/[éèêëàâäôöûüçœ]/gi) || []).length;
|
|
67
67
|
const germanChars = (text.match(/[äöüß]/gi) || []).length;
|
|
68
68
|
const spanishChars = (text.match(/[ñáéíóú¿¡]/gi) || []).length;
|
|
69
|
-
|
|
69
|
+
|
|
70
70
|
// If French is dominant
|
|
71
71
|
if (frenchChars > 0 && frenchChars >= germanChars && frenchChars >= spanishChars) {
|
|
72
72
|
return text
|
|
73
73
|
.replace(/(^|\s)"(.*?)"(?=\s|$|[.,!?])/g, "$1« $2 »")
|
|
74
74
|
.replace(/(^|\s)'(.*?)'(?=\s|$|[.,!?])/g, "$1‹ $2 ›")
|
|
75
75
|
.replace(/--/g, "\u2014");
|
|
76
|
-
}
|
|
76
|
+
}
|
|
77
77
|
// If German is dominant
|
|
78
78
|
else if (germanChars > 0 && germanChars > frenchChars && germanChars >= spanishChars) {
|
|
79
79
|
return text
|
|
80
80
|
.replace(/(^|\s)"(.*?)"(?=\s|$|[.,!?])/g, "$1„$2“")
|
|
81
81
|
.replace(/(^|\s)'(.*?)'(?=\s|$|[.,!?])/g, "$1‚$2‘")
|
|
82
82
|
.replace(/--/g, "\u2014");
|
|
83
|
-
}
|
|
83
|
+
}
|
|
84
84
|
// If Spanish is dominant
|
|
85
85
|
else if (spanishChars > 0 && spanishChars > frenchChars && spanishChars > germanChars) {
|
|
86
86
|
return text
|
|
@@ -104,34 +104,34 @@ function renderMathFormulas(text) {
|
|
|
104
104
|
let html = text;
|
|
105
105
|
const blockMathRegex = /\$\$\s*([\s\S]*?)\s*\$\$/g;
|
|
106
106
|
const inlineMathRegex = /\$(?!\s)([^$\n]+?)(?<!\s)\$/g;
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
let hasMath = false;
|
|
109
|
-
|
|
109
|
+
|
|
110
110
|
html = html.replace(blockMathRegex, (match, formula) => {
|
|
111
111
|
hasMath = true;
|
|
112
112
|
const encoded = encodeURIComponent(formula.trim());
|
|
113
113
|
return `<div style="text-align: center; margin: 1em 0;"><img src="https://latex.codecogs.com/svg.image?${encoded}" alt="${formula.replace(/"/g, '"')}" /></div>`;
|
|
114
114
|
});
|
|
115
|
-
|
|
115
|
+
|
|
116
116
|
html = html.replace(inlineMathRegex, (match, formula) => {
|
|
117
117
|
hasMath = true;
|
|
118
118
|
const encoded = encodeURIComponent(formula.trim());
|
|
119
119
|
return `<img style="vertical-align: middle;" src="https://latex.codecogs.com/svg.image?${encoded}" alt="${formula.replace(/"/g, '"')}" />`;
|
|
120
120
|
});
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
return { hasMath, html };
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
function isMarkdown(text) {
|
|
126
126
|
// Simple heuristic: contains headings, lists, bold, links, or tables
|
|
127
|
-
return /^#+\s/m.test(text) ||
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
return /^#+\s/m.test(text) ||
|
|
128
|
+
/\*\*[^*]+\*\*/.test(text) ||
|
|
129
|
+
/\[.+?\]\(.+?\)/.test(text) ||
|
|
130
|
+
/^\s*[-*+]\s/m.test(text) ||
|
|
131
|
+
/^\s*\d+\.\s/m.test(text) ||
|
|
132
|
+
/`[^`]+`/.test(text) ||
|
|
133
|
+
/^> /m.test(text) ||
|
|
134
|
+
(text.includes('|') && /^[-:| ]+$/m.test(text));
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
async function convertMarkdownToHTML(text) {
|
|
@@ -159,6 +159,24 @@ function normalizeShouting(text) {
|
|
|
159
159
|
async function processClipboard(text, originalHtml) {
|
|
160
160
|
let result = { changed: false, text: text, html: originalHtml };
|
|
161
161
|
|
|
162
|
+
// PRESERVATION HEURISTIC: Yield if high-quality HTML already exists
|
|
163
|
+
if (originalHtml) {
|
|
164
|
+
const forensicMarkers = [
|
|
165
|
+
'data-sheets-value',
|
|
166
|
+
'data-sheets-userformat',
|
|
167
|
+
'br-re-calc',
|
|
168
|
+
'x-office-spreadsheet',
|
|
169
|
+
'<table>',
|
|
170
|
+
'<tbody>',
|
|
171
|
+
'<thead>'
|
|
172
|
+
];
|
|
173
|
+
|
|
174
|
+
const hasStructure = forensicMarkers.some(marker => originalHtml.toLowerCase().includes(marker));
|
|
175
|
+
if (hasStructure) {
|
|
176
|
+
return { changed: false, text: text, html: originalHtml, skipReason: 'Forensic structure detected' };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
162
180
|
// 0. Case Normalization (Shouting)
|
|
163
181
|
const normalizedText = normalizeShouting(text);
|
|
164
182
|
if (normalizedText !== text) {
|
|
@@ -65,15 +65,15 @@ Error generating stack: `+l.message+`
|
|
|
65
65
|
* @license MIT
|
|
66
66
|
*/var og="popstate";function cg(a){return typeof a=="object"&&a!=null&&"pathname"in a&&"search"in a&&"hash"in a&&"state"in a&&"key"in a}function kA(a={}){function i(u,c){var p;let h=(p=c.state)==null?void 0:p.masked,{pathname:f,search:m,hash:y}=h||u.location;return Jc("",{pathname:f,search:m,hash:y},c.state&&c.state.usr||null,c.state&&c.state.key||"default",h?{pathname:u.location.pathname,search:u.location.search,hash:u.location.hash}:void 0)}function s(u,c){return typeof c=="string"?c:Nl(c)}return FA(i,s,null,a)}function _t(a,i){if(a===!1||a===null||typeof a>"u")throw new Error(i)}function nn(a,i){if(!a){typeof console<"u"&&console.warn(i);try{throw new Error(i)}catch{}}}function JA(){return Math.random().toString(36).substring(2,10)}function fg(a,i){return{usr:a.state,key:a.key,idx:i,masked:a.unstable_mask?{pathname:a.pathname,search:a.search,hash:a.hash}:void 0}}function Jc(a,i,s=null,u,c){return{pathname:typeof a=="string"?a:a.pathname,search:"",hash:"",...typeof i=="string"?Ai(i):i,state:s,key:i&&i.key||u||JA(),unstable_mask:c}}function Nl({pathname:a="/",search:i="",hash:s=""}){return i&&i!=="?"&&(a+=i.charAt(0)==="?"?i:"?"+i),s&&s!=="#"&&(a+=s.charAt(0)==="#"?s:"#"+s),a}function Ai(a){let i={};if(a){let s=a.indexOf("#");s>=0&&(i.hash=a.substring(s),a=a.substring(0,s));let u=a.indexOf("?");u>=0&&(i.search=a.substring(u),a=a.substring(0,u)),a&&(i.pathname=a)}return i}function FA(a,i,s,u={}){let{window:c=document.defaultView,v5Compat:h=!1}=u,f=c.history,m="POP",y=null,p=g();p==null&&(p=0,f.replaceState({...f.state,idx:p},""));function g(){return(f.state||{idx:null}).idx}function S(){m="POP";let N=g(),O=N==null?null:N-p;p=N,y&&y({action:m,location:V.location,delta:O})}function b(N,O){m="PUSH";let G=cg(N)?N:Jc(V.location,N,O);p=g()+1;let B=fg(G,p),Q=V.createHref(G.unstable_mask||G);try{f.pushState(B,"",Q)}catch(X){if(X instanceof DOMException&&X.name==="DataCloneError")throw X;c.location.assign(Q)}h&&y&&y({action:m,location:V.location,delta:1})}function A(N,O){m="REPLACE";let G=cg(N)?N:Jc(V.location,N,O);p=g();let B=fg(G,p),Q=V.createHref(G.unstable_mask||G);f.replaceState(B,"",Q),h&&y&&y({action:m,location:V.location,delta:0})}function D(N){return PA(N)}let V={get action(){return m},get location(){return a(c,f)},listen(N){if(y)throw new Error("A history only accepts one active listener");return c.addEventListener(og,S),y=N,()=>{c.removeEventListener(og,S),y=null}},createHref(N){return i(c,N)},createURL:D,encodeLocation(N){let O=D(N);return{pathname:O.pathname,search:O.search,hash:O.hash}},push:b,replace:A,go(N){return f.go(N)}};return V}function PA(a,i=!1){let s="http://localhost";typeof window<"u"&&(s=window.location.origin!=="null"?window.location.origin:window.location.href),_t(s,"No window.location.(origin|href) available to create URL");let u=typeof a=="string"?a:Nl(a);return u=u.replace(/ $/,"%20"),!i&&u.startsWith("//")&&(u=s+u),new URL(u,s)}function n0(a,i,s="/"){return WA(a,i,s,!1)}function WA(a,i,s,u){let c=typeof i=="string"?Ai(i):i,h=Mn(c.pathname||"/",s);if(h==null)return null;let f=a0(a);$A(f);let m=null;for(let y=0;m==null&&y<f.length;++y){let p=o2(h);m=u2(f[y],p,u)}return m}function a0(a,i=[],s=[],u="",c=!1){let h=(f,m,y=c,p)=>{let g={relativePath:p===void 0?f.path||"":p,caseSensitive:f.caseSensitive===!0,childrenIndex:m,route:f};if(g.relativePath.startsWith("/")){if(!g.relativePath.startsWith(u)&&y)return;_t(g.relativePath.startsWith(u),`Absolute route path "${g.relativePath}" nested under path "${u}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),g.relativePath=g.relativePath.slice(u.length)}let S=tn([u,g.relativePath]),b=s.concat(g);f.children&&f.children.length>0&&(_t(f.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${S}".`),a0(f.children,i,b,S,y)),!(f.path==null&&!f.index)&&i.push({path:S,score:l2(S,f.index),routesMeta:b})};return a.forEach((f,m)=>{var y;if(f.path===""||!((y=f.path)!=null&&y.includes("?")))h(f,m);else for(let p of i0(f.path))h(f,m,!0,p)}),i}function i0(a){let i=a.split("/");if(i.length===0)return[];let[s,...u]=i,c=s.endsWith("?"),h=s.replace(/\?$/,"");if(u.length===0)return c?[h,""]:[h];let f=i0(u.join("/")),m=[];return m.push(...f.map(y=>y===""?h:[h,y].join("/"))),c&&m.push(...f),m.map(y=>a.startsWith("/")&&y===""?"/":y)}function $A(a){a.sort((i,s)=>i.score!==s.score?s.score-i.score:s2(i.routesMeta.map(u=>u.childrenIndex),s.routesMeta.map(u=>u.childrenIndex)))}var IA=/^:[\w-]+$/,t2=3,e2=2,n2=1,a2=10,i2=-2,hg=a=>a==="*";function l2(a,i){let s=a.split("/"),u=s.length;return s.some(hg)&&(u+=i2),i&&(u+=e2),s.filter(c=>!hg(c)).reduce((c,h)=>c+(IA.test(h)?t2:h===""?n2:a2),u)}function s2(a,i){return a.length===i.length&&a.slice(0,-1).every((u,c)=>u===i[c])?a[a.length-1]-i[i.length-1]:0}function u2(a,i,s=!1){let{routesMeta:u}=a,c={},h="/",f=[];for(let m=0;m<u.length;++m){let y=u[m],p=m===u.length-1,g=h==="/"?i:i.slice(h.length)||"/",S=Ru({path:y.relativePath,caseSensitive:y.caseSensitive,end:p},g),b=y.route;if(!S&&p&&s&&!u[u.length-1].route.index&&(S=Ru({path:y.relativePath,caseSensitive:y.caseSensitive,end:!1},g)),!S)return null;Object.assign(c,S.params),f.push({params:c,pathname:tn([h,S.pathname]),pathnameBase:d2(tn([h,S.pathnameBase])),route:b}),S.pathnameBase!=="/"&&(h=tn([h,S.pathnameBase]))}return f}function Ru(a,i){typeof a=="string"&&(a={path:a,caseSensitive:!1,end:!0});let[s,u]=r2(a.path,a.caseSensitive,a.end),c=i.match(s);if(!c)return null;let h=c[0],f=h.replace(/(.)\/+$/,"$1"),m=c.slice(1);return{params:u.reduce((p,{paramName:g,isOptional:S},b)=>{if(g==="*"){let D=m[b]||"";f=h.slice(0,h.length-D.length).replace(/(.)\/+$/,"$1")}const A=m[b];return S&&!A?p[g]=void 0:p[g]=(A||"").replace(/%2F/g,"/"),p},{}),pathname:h,pathnameBase:f,pattern:a}}function r2(a,i=!1,s=!0){nn(a==="*"||!a.endsWith("*")||a.endsWith("/*"),`Route path "${a}" will be treated as if it were "${a.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${a.replace(/\*$/,"/*")}".`);let u=[],c="^"+a.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(f,m,y,p,g)=>{if(u.push({paramName:m,isOptional:y!=null}),y){let S=g.charAt(p+f.length);return S&&S!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return a.endsWith("*")?(u.push({paramName:"*"}),c+=a==="*"||a==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):s?c+="\\/*$":a!==""&&a!=="/"&&(c+="(?:(?=\\/|$))"),[new RegExp(c,i?void 0:"i"),u]}function o2(a){try{return a.split("/").map(i=>decodeURIComponent(i).replace(/\//g,"%2F")).join("/")}catch(i){return nn(!1,`The URL path "${a}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${i}).`),a}}function Mn(a,i){if(i==="/")return a;if(!a.toLowerCase().startsWith(i.toLowerCase()))return null;let s=i.endsWith("/")?i.length-1:i.length,u=a.charAt(s);return u&&u!=="/"?null:a.slice(s)||"/"}var c2=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;function f2(a,i="/"){let{pathname:s,search:u="",hash:c=""}=typeof a=="string"?Ai(a):a,h;return s?(s=s.replace(/\/\/+/g,"/"),s.startsWith("/")?h=dg(s.substring(1),"/"):h=dg(s,i)):h=i,{pathname:h,search:m2(u),hash:p2(c)}}function dg(a,i){let s=i.replace(/\/+$/,"").split("/");return a.split("/").forEach(c=>{c===".."?s.length>1&&s.pop():c!=="."&&s.push(c)}),s.length>1?s.join("/"):"/"}function xc(a,i,s,u){return`Cannot include a '${a}' character in a manually specified \`to.${i}\` field [${JSON.stringify(u)}]. Please separate it out to the \`to.${s}\` field. Alternatively you may provide the full path as a string in <Link to="..."> and the router will parse it for you.`}function h2(a){return a.filter((i,s)=>s===0||i.route.path&&i.route.path.length>0)}function l0(a){let i=h2(a);return i.map((s,u)=>u===i.length-1?s.pathname:s.pathnameBase)}function Of(a,i,s,u=!1){let c;typeof a=="string"?c=Ai(a):(c={...a},_t(!c.pathname||!c.pathname.includes("?"),xc("?","pathname","search",c)),_t(!c.pathname||!c.pathname.includes("#"),xc("#","pathname","hash",c)),_t(!c.search||!c.search.includes("#"),xc("#","search","hash",c)));let h=a===""||c.pathname==="",f=h?"/":c.pathname,m;if(f==null)m=s;else{let S=i.length-1;if(!u&&f.startsWith("..")){let b=f.split("/");for(;b[0]==="..";)b.shift(),S-=1;c.pathname=b.join("/")}m=S>=0?i[S]:"/"}let y=f2(c,m),p=f&&f!=="/"&&f.endsWith("/"),g=(h||f===".")&&s.endsWith("/");return!y.pathname.endsWith("/")&&(p||g)&&(y.pathname+="/"),y}var tn=a=>a.join("/").replace(/\/\/+/g,"/"),d2=a=>a.replace(/\/+$/,"").replace(/^\/*/,"/"),m2=a=>!a||a==="?"?"":a.startsWith("?")?a:"?"+a,p2=a=>!a||a==="#"?"":a.startsWith("#")?a:"#"+a,y2=class{constructor(a,i,s,u=!1){this.status=a,this.statusText=i||"",this.internal=u,s instanceof Error?(this.data=s.toString(),this.error=s):this.data=s}};function g2(a){return a!=null&&typeof a.status=="number"&&typeof a.statusText=="string"&&typeof a.internal=="boolean"&&"data"in a}function v2(a){return a.map(i=>i.route.path).filter(Boolean).join("/").replace(/\/\/*/g,"/")||"/"}var s0=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function u0(a,i){let s=a;if(typeof s!="string"||!c2.test(s))return{absoluteURL:void 0,isExternal:!1,to:s};let u=s,c=!1;if(s0)try{let h=new URL(window.location.href),f=s.startsWith("//")?new URL(h.protocol+s):new URL(s),m=Mn(f.pathname,i);f.origin===h.origin&&m!=null?s=m+f.search+f.hash:c=!0}catch{nn(!1,`<Link to="${s}"> contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:u,isExternal:c,to:s}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var r0=["POST","PUT","PATCH","DELETE"];new Set(r0);var S2=["GET",...r0];new Set(S2);var Mi=M.createContext(null);Mi.displayName="DataRouter";var wu=M.createContext(null);wu.displayName="DataRouterState";var b2=M.createContext(!1),o0=M.createContext({isTransitioning:!1});o0.displayName="ViewTransition";var x2=M.createContext(new Map);x2.displayName="Fetchers";var T2=M.createContext(null);T2.displayName="Await";var qe=M.createContext(null);qe.displayName="Navigation";var Ll=M.createContext(null);Ll.displayName="Location";var Rn=M.createContext({outlet:null,matches:[],isDataRoute:!1});Rn.displayName="Route";var wf=M.createContext(null);wf.displayName="RouteError";var c0="REACT_ROUTER_ERROR",E2="REDIRECT",A2="ROUTE_ERROR_RESPONSE";function M2(a){if(a.startsWith(`${c0}:${E2}:{`))try{let i=JSON.parse(a.slice(28));if(typeof i=="object"&&i&&typeof i.status=="number"&&typeof i.statusText=="string"&&typeof i.location=="string"&&typeof i.reloadDocument=="boolean"&&typeof i.replace=="boolean")return i}catch{}}function R2(a){if(a.startsWith(`${c0}:${A2}:{`))try{let i=JSON.parse(a.slice(40));if(typeof i=="object"&&i&&typeof i.status=="number"&&typeof i.statusText=="string")return new y2(i.status,i.statusText,i.data)}catch{}}function D2(a,{relative:i}={}){_t(Hl(),"useHref() may be used only in the context of a <Router> component.");let{basename:s,navigator:u}=M.useContext(qe),{hash:c,pathname:h,search:f}=ql(a,{relative:i}),m=h;return s!=="/"&&(m=h==="/"?s:tn([s,h])),u.createHref({pathname:m,search:f,hash:c})}function Hl(){return M.useContext(Ll)!=null}function Dn(){return _t(Hl(),"useLocation() may be used only in the context of a <Router> component."),M.useContext(Ll).location}var f0="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function h0(a){M.useContext(qe).static||M.useLayoutEffect(a)}function C2(){let{isDataRoute:a}=M.useContext(Rn);return a?Y2():z2()}function z2(){_t(Hl(),"useNavigate() may be used only in the context of a <Router> component.");let a=M.useContext(Mi),{basename:i,navigator:s}=M.useContext(qe),{matches:u}=M.useContext(Rn),{pathname:c}=Dn(),h=JSON.stringify(l0(u)),f=M.useRef(!1);return h0(()=>{f.current=!0}),M.useCallback((y,p={})=>{if(nn(f.current,f0),!f.current)return;if(typeof y=="number"){s.go(y);return}let g=Of(y,JSON.parse(h),c,p.relative==="path");a==null&&i!=="/"&&(g.pathname=g.pathname==="/"?i:tn([i,g.pathname])),(p.replace?s.replace:s.push)(g,p.state,p)},[i,s,h,c,a])}M.createContext(null);function ql(a,{relative:i}={}){let{matches:s}=M.useContext(Rn),{pathname:u}=Dn(),c=JSON.stringify(l0(s));return M.useMemo(()=>Of(a,JSON.parse(c),u,i==="path"),[a,c,u,i])}function O2(a,i){return d0(a,i)}function d0(a,i,s){var N;_t(Hl(),"useRoutes() may be used only in the context of a <Router> component.");let{navigator:u}=M.useContext(qe),{matches:c}=M.useContext(Rn),h=c[c.length-1],f=h?h.params:{},m=h?h.pathname:"/",y=h?h.pathnameBase:"/",p=h&&h.route;{let O=p&&p.path||"";p0(m,!p||O.endsWith("*")||O.endsWith("*?"),`You rendered descendant <Routes> (or called \`useRoutes()\`) at "${m}" (under <Route path="${O}">) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render.
|
|
67
67
|
|
|
68
|
-
Please change the parent <Route path="${O}"> to <Route path="${O==="/"?"*":`${O}/*`}">.`)}let g=Dn(),S;if(i){let O=typeof i=="string"?Ai(i):i;_t(y==="/"||((N=O.pathname)==null?void 0:N.startsWith(y)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${y}" but pathname "${O.pathname}" was given in the \`location\` prop.`),S=O}else S=g;let b=S.pathname||"/",A=b;if(y!=="/"){let O=y.replace(/^\//,"").split("/");A="/"+b.replace(/^\//,"").split("/").slice(O.length).join("/")}let D=n0(a,{pathname:A});nn(p||D!=null,`No routes matched location "${S.pathname}${S.search}${S.hash}" `),nn(D==null||D[D.length-1].route.element!==void 0||D[D.length-1].route.Component!==void 0||D[D.length-1].route.lazy!==void 0,`Matched leaf route at location "${S.pathname}${S.search}${S.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let V=U2(D&&D.map(O=>Object.assign({},O,{params:Object.assign({},f,O.params),pathname:tn([y,u.encodeLocation?u.encodeLocation(O.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:O.pathname]),pathnameBase:O.pathnameBase==="/"?y:tn([y,u.encodeLocation?u.encodeLocation(O.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:O.pathnameBase])})),c,s);return i&&V?M.createElement(Ll.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...S},navigationType:"POP"}},V):V}function w2(){let a=q2(),i=g2(a)?`${a.status} ${a.statusText}`:a instanceof Error?a.message:JSON.stringify(a),s=a instanceof Error?a.stack:null,u="rgba(200,200,200, 0.5)",c={padding:"0.5rem",backgroundColor:u},h={padding:"2px 4px",backgroundColor:u},f=null;return console.error("Error handled by React Router default ErrorBoundary:",a),f=M.createElement(M.Fragment,null,M.createElement("p",null,"💿 Hey developer 👋"),M.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",M.createElement("code",{style:h},"ErrorBoundary")," or"," ",M.createElement("code",{style:h},"errorElement")," prop on your route.")),M.createElement(M.Fragment,null,M.createElement("h2",null,"Unexpected Application Error!"),M.createElement("h3",{style:{fontStyle:"italic"}},i),s?M.createElement("pre",{style:c},s):null,f)}var V2=M.createElement(w2,null),m0=class extends M.Component{constructor(a){super(a),this.state={location:a.location,revalidation:a.revalidation,error:a.error}}static getDerivedStateFromError(a){return{error:a}}static getDerivedStateFromProps(a,i){return i.location!==a.location||i.revalidation!=="idle"&&a.revalidation==="idle"?{error:a.error,location:a.location,revalidation:a.revalidation}:{error:a.error!==void 0?a.error:i.error,location:i.location,revalidation:a.revalidation||i.revalidation}}componentDidCatch(a,i){this.props.onError?this.props.onError(a,i):console.error("React Router caught the following error during render",a)}render(){let a=this.state.error;if(this.context&&typeof a=="object"&&a&&"digest"in a&&typeof a.digest=="string"){const s=R2(a.digest);s&&(a=s)}let i=a!==void 0?M.createElement(Rn.Provider,{value:this.props.routeContext},M.createElement(wf.Provider,{value:a,children:this.props.component})):this.props.children;return this.context?M.createElement(N2,{error:a},i):i}};m0.contextType=b2;var Tc=new WeakMap;function N2({children:a,error:i}){let{basename:s}=M.useContext(qe);if(typeof i=="object"&&i&&"digest"in i&&typeof i.digest=="string"){let u=M2(i.digest);if(u){let c=Tc.get(i);if(c)throw c;let h=u0(u.location,s);if(s0&&!Tc.get(i))if(h.isExternal||u.reloadDocument)window.location.href=h.absoluteURL||h.to;else{const f=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(h.to,{replace:u.replace}));throw Tc.set(i,f),f}return M.createElement("meta",{httpEquiv:"refresh",content:`0;url=${h.absoluteURL||h.to}`})}}return a}function _2({routeContext:a,match:i,children:s}){let u=M.useContext(Mi);return u&&u.static&&u.staticContext&&(i.route.errorElement||i.route.ErrorBoundary)&&(u.staticContext._deepestRenderedBoundaryId=i.route.id),M.createElement(Rn.Provider,{value:a},s)}function U2(a,i=[],s){let u=s==null?void 0:s.state;if(a==null){if(!u)return null;if(u.errors)a=u.matches;else if(i.length===0&&!u.initialized&&u.matches.length>0)a=u.matches;else return null}let c=a,h=u==null?void 0:u.errors;if(h!=null){let g=c.findIndex(S=>S.route.id&&(h==null?void 0:h[S.route.id])!==void 0);_t(g>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(h).join(",")}`),c=c.slice(0,Math.min(c.length,g+1))}let f=!1,m=-1;if(s&&u){f=u.renderFallback;for(let g=0;g<c.length;g++){let S=c[g];if((S.route.HydrateFallback||S.route.hydrateFallbackElement)&&(m=g),S.route.id){let{loaderData:b,errors:A}=u,D=S.route.loader&&!b.hasOwnProperty(S.route.id)&&(!A||A[S.route.id]===void 0);if(S.route.lazy||D){s.isStatic&&(f=!0),m>=0?c=c.slice(0,m+1):c=[c[0]];break}}}}let y=s==null?void 0:s.onError,p=u&&y?(g,S)=>{var b,A;y(g,{location:u.location,params:((A=(b=u.matches)==null?void 0:b[0])==null?void 0:A.params)??{},unstable_pattern:v2(u.matches),errorInfo:S})}:void 0;return c.reduceRight((g,S,b)=>{let A,D=!1,V=null,N=null;u&&(A=h&&S.route.id?h[S.route.id]:void 0,V=S.route.errorElement||V2,f&&(m<0&&b===0?(p0("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),D=!0,N=null):m===b&&(D=!0,N=S.route.hydrateFallbackElement||null)));let O=i.concat(c.slice(0,b+1)),G=()=>{let B;return A?B=V:D?B=N:S.route.Component?B=M.createElement(S.route.Component,null):S.route.element?B=S.route.element:B=g,M.createElement(_2,{match:S,routeContext:{outlet:g,matches:O,isDataRoute:u!=null},children:B})};return u&&(S.route.ErrorBoundary||S.route.errorElement||b===0)?M.createElement(m0,{location:u.location,revalidation:u.revalidation,component:V,error:A,children:G(),routeContext:{outlet:null,matches:O,isDataRoute:!0},onError:p}):G()},null)}function Vf(a){return`${a} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function j2(a){let i=M.useContext(Mi);return _t(i,Vf(a)),i}function B2(a){let i=M.useContext(wu);return _t(i,Vf(a)),i}function L2(a){let i=M.useContext(Rn);return _t(i,Vf(a)),i}function Nf(a){let i=L2(a),s=i.matches[i.matches.length-1];return _t(s.route.id,`${a} can only be used on routes that contain a unique "id"`),s.route.id}function H2(){return Nf("useRouteId")}function q2(){var u;let a=M.useContext(wf),i=B2("useRouteError"),s=Nf("useRouteError");return a!==void 0?a:(u=i.errors)==null?void 0:u[s]}function Y2(){let{router:a}=j2("useNavigate"),i=Nf("useNavigate"),s=M.useRef(!1);return h0(()=>{s.current=!0}),M.useCallback(async(c,h={})=>{nn(s.current,f0),s.current&&(typeof c=="number"?await a.navigate(c):await a.navigate(c,{fromRouteId:i,...h}))},[a,i])}var mg={};function p0(a,i,s){!i&&!mg[a]&&(mg[a]=!0,nn(!1,s))}M.memo(G2);function G2({routes:a,future:i,state:s,isStatic:u,onError:c}){return d0(a,void 0,{state:s,isStatic:u,onError:c})}function Fc(a){_t(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function X2({basename:a="/",children:i=null,location:s,navigationType:u="POP",navigator:c,static:h=!1,unstable_useTransitions:f}){_t(!Hl(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let m=a.replace(/^\/*/,"/"),y=M.useMemo(()=>({basename:m,navigator:c,static:h,unstable_useTransitions:f,future:{}}),[m,c,h,f]);typeof s=="string"&&(s=Ai(s));let{pathname:p="/",search:g="",hash:S="",state:b=null,key:A="default",unstable_mask:D}=s,V=M.useMemo(()=>{let N=Mn(p,m);return N==null?null:{location:{pathname:N,search:g,hash:S,state:b,key:A,unstable_mask:D},navigationType:u}},[m,p,g,S,b,A,u,D]);return nn(V!=null,`<Router basename="${m}"> is not able to match the URL "${p}${g}${S}" because it does not start with the basename, so the <Router> won't render anything.`),V==null?null:M.createElement(qe.Provider,{value:y},M.createElement(Ll.Provider,{children:i,value:V}))}function K2({children:a,location:i}){return O2(Pc(a),i)}function Pc(a,i=[]){let s=[];return M.Children.forEach(a,(u,c)=>{if(!M.isValidElement(u))return;let h=[...i,c];if(u.type===M.Fragment){s.push.apply(s,Pc(u.props.children,h));return}_t(u.type===Fc,`[${typeof u.type=="string"?u.type:u.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),_t(!u.props.index||!u.props.children,"An index route cannot have child routes.");let f={id:u.props.id||h.join("-"),caseSensitive:u.props.caseSensitive,element:u.props.element,Component:u.props.Component,index:u.props.index,path:u.props.path,middleware:u.props.middleware,loader:u.props.loader,action:u.props.action,hydrateFallbackElement:u.props.hydrateFallbackElement,HydrateFallback:u.props.HydrateFallback,errorElement:u.props.errorElement,ErrorBoundary:u.props.ErrorBoundary,hasErrorBoundary:u.props.hasErrorBoundary===!0||u.props.ErrorBoundary!=null||u.props.errorElement!=null,shouldRevalidate:u.props.shouldRevalidate,handle:u.props.handle,lazy:u.props.lazy};u.props.children&&(f.children=Pc(u.props.children,h)),s.push(f)}),s}var yu="get",gu="application/x-www-form-urlencoded";function Vu(a){return typeof HTMLElement<"u"&&a instanceof HTMLElement}function Q2(a){return Vu(a)&&a.tagName.toLowerCase()==="button"}function Z2(a){return Vu(a)&&a.tagName.toLowerCase()==="form"}function k2(a){return Vu(a)&&a.tagName.toLowerCase()==="input"}function J2(a){return!!(a.metaKey||a.altKey||a.ctrlKey||a.shiftKey)}function F2(a,i){return a.button===0&&(!i||i==="_self")&&!J2(a)}var ou=null;function P2(){if(ou===null)try{new FormData(document.createElement("form"),0),ou=!1}catch{ou=!0}return ou}var W2=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Ec(a){return a!=null&&!W2.has(a)?(nn(!1,`"${a}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${gu}"`),null):a}function $2(a,i){let s,u,c,h,f;if(Z2(a)){let m=a.getAttribute("action");u=m?Mn(m,i):null,s=a.getAttribute("method")||yu,c=Ec(a.getAttribute("enctype"))||gu,h=new FormData(a)}else if(Q2(a)||k2(a)&&(a.type==="submit"||a.type==="image")){let m=a.form;if(m==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let y=a.getAttribute("formaction")||m.getAttribute("action");if(u=y?Mn(y,i):null,s=a.getAttribute("formmethod")||m.getAttribute("method")||yu,c=Ec(a.getAttribute("formenctype"))||Ec(m.getAttribute("enctype"))||gu,h=new FormData(m,a),!P2()){let{name:p,type:g,value:S}=a;if(g==="image"){let b=p?`${p}.`:"";h.append(`${b}x`,"0"),h.append(`${b}y`,"0")}else p&&h.append(p,S)}}else{if(Vu(a))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');s=yu,u=null,c=gu,f=a}return h&&c==="text/plain"&&(f=h,h=void 0),{action:u,method:s.toLowerCase(),encType:c,formData:h,body:f}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function _f(a,i){if(a===!1||a===null||typeof a>"u")throw new Error(i)}function I2(a,i,s,u){let c=typeof a=="string"?new URL(a,typeof window>"u"?"server://singlefetch/":window.location.origin):a;return s?c.pathname.endsWith("/")?c.pathname=`${c.pathname}_.${u}`:c.pathname=`${c.pathname}.${u}`:c.pathname==="/"?c.pathname=`_root.${u}`:i&&Mn(c.pathname,i)==="/"?c.pathname=`${i.replace(/\/$/,"")}/_root.${u}`:c.pathname=`${c.pathname.replace(/\/$/,"")}.${u}`,c}async function tM(a,i){if(a.id in i)return i[a.id];try{let s=await import(a.module);return i[a.id]=s,s}catch(s){return console.error(`Error loading route module \`${a.module}\`, reloading page...`),console.error(s),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function eM(a){return a==null?!1:a.href==null?a.rel==="preload"&&typeof a.imageSrcSet=="string"&&typeof a.imageSizes=="string":typeof a.rel=="string"&&typeof a.href=="string"}async function nM(a,i,s){let u=await Promise.all(a.map(async c=>{let h=i.routes[c.route.id];if(h){let f=await tM(h,s);return f.links?f.links():[]}return[]}));return sM(u.flat(1).filter(eM).filter(c=>c.rel==="stylesheet"||c.rel==="preload").map(c=>c.rel==="stylesheet"?{...c,rel:"prefetch",as:"style"}:{...c,rel:"prefetch"}))}function pg(a,i,s,u,c,h){let f=(y,p)=>s[p]?y.route.id!==s[p].route.id:!0,m=(y,p)=>{var g;return s[p].pathname!==y.pathname||((g=s[p].route.path)==null?void 0:g.endsWith("*"))&&s[p].params["*"]!==y.params["*"]};return h==="assets"?i.filter((y,p)=>f(y,p)||m(y,p)):h==="data"?i.filter((y,p)=>{var S;let g=u.routes[y.route.id];if(!g||!g.hasLoader)return!1;if(f(y,p)||m(y,p))return!0;if(y.route.shouldRevalidate){let b=y.route.shouldRevalidate({currentUrl:new URL(c.pathname+c.search+c.hash,window.origin),currentParams:((S=s[0])==null?void 0:S.params)||{},nextUrl:new URL(a,window.origin),nextParams:y.params,defaultShouldRevalidate:!0});if(typeof b=="boolean")return b}return!0}):[]}function aM(a,i,{includeHydrateFallback:s}={}){return iM(a.map(u=>{let c=i.routes[u.route.id];if(!c)return[];let h=[c.module];return c.clientActionModule&&(h=h.concat(c.clientActionModule)),c.clientLoaderModule&&(h=h.concat(c.clientLoaderModule)),s&&c.hydrateFallbackModule&&(h=h.concat(c.hydrateFallbackModule)),c.imports&&(h=h.concat(c.imports)),h}).flat(1))}function iM(a){return[...new Set(a)]}function lM(a){let i={},s=Object.keys(a).sort();for(let u of s)i[u]=a[u];return i}function sM(a,i){let s=new Set;return new Set(i),a.reduce((u,c)=>{let h=JSON.stringify(lM(c));return s.has(h)||(s.add(h),u.push({key:h,link:c})),u},[])}function y0(){let a=M.useContext(Mi);return _f(a,"You must render this element inside a <DataRouterContext.Provider> element"),a}function uM(){let a=M.useContext(wu);return _f(a,"You must render this element inside a <DataRouterStateContext.Provider> element"),a}var Uf=M.createContext(void 0);Uf.displayName="FrameworkContext";function g0(){let a=M.useContext(Uf);return _f(a,"You must render this element inside a <HydratedRouter> element"),a}function rM(a,i){let s=M.useContext(Uf),[u,c]=M.useState(!1),[h,f]=M.useState(!1),{onFocus:m,onBlur:y,onMouseEnter:p,onMouseLeave:g,onTouchStart:S}=i,b=M.useRef(null);M.useEffect(()=>{if(a==="render"&&f(!0),a==="viewport"){let V=O=>{O.forEach(G=>{f(G.isIntersecting)})},N=new IntersectionObserver(V,{threshold:.5});return b.current&&N.observe(b.current),()=>{N.disconnect()}}},[a]),M.useEffect(()=>{if(u){let V=setTimeout(()=>{f(!0)},100);return()=>{clearTimeout(V)}}},[u]);let A=()=>{c(!0)},D=()=>{c(!1),f(!1)};return s?a!=="intent"?[h,b,{}]:[h,b,{onFocus:Tl(m,A),onBlur:Tl(y,D),onMouseEnter:Tl(p,A),onMouseLeave:Tl(g,D),onTouchStart:Tl(S,A)}]:[!1,b,{}]}function Tl(a,i){return s=>{a&&a(s),s.defaultPrevented||i(s)}}function oM({page:a,...i}){let{router:s}=y0(),u=M.useMemo(()=>n0(s.routes,a,s.basename),[s.routes,a,s.basename]);return u?M.createElement(fM,{page:a,matches:u,...i}):null}function cM(a){let{manifest:i,routeModules:s}=g0(),[u,c]=M.useState([]);return M.useEffect(()=>{let h=!1;return nM(a,i,s).then(f=>{h||c(f)}),()=>{h=!0}},[a,i,s]),u}function fM({page:a,matches:i,...s}){let u=Dn(),{future:c,manifest:h,routeModules:f}=g0(),{basename:m}=y0(),{loaderData:y,matches:p}=uM(),g=M.useMemo(()=>pg(a,i,p,h,u,"data"),[a,i,p,h,u]),S=M.useMemo(()=>pg(a,i,p,h,u,"assets"),[a,i,p,h,u]),b=M.useMemo(()=>{if(a===u.pathname+u.search+u.hash)return[];let V=new Set,N=!1;if(i.forEach(G=>{var Q;let B=h.routes[G.route.id];!B||!B.hasLoader||(!g.some(X=>X.route.id===G.route.id)&&G.route.id in y&&((Q=f[G.route.id])!=null&&Q.shouldRevalidate)||B.hasClientLoader?N=!0:V.add(G.route.id))}),V.size===0)return[];let O=I2(a,m,c.unstable_trailingSlashAwareDataRequests,"data");return N&&V.size>0&&O.searchParams.set("_routes",i.filter(G=>V.has(G.route.id)).map(G=>G.route.id).join(",")),[O.pathname+O.search]},[m,c.unstable_trailingSlashAwareDataRequests,y,u,h,g,i,a,f]),A=M.useMemo(()=>aM(S,h),[S,h]),D=cM(S);return M.createElement(M.Fragment,null,b.map(V=>M.createElement("link",{key:V,rel:"prefetch",as:"fetch",href:V,...s})),A.map(V=>M.createElement("link",{key:V,rel:"modulepreload",href:V,...s})),D.map(({key:V,link:N})=>M.createElement("link",{key:V,nonce:s.nonce,...N,crossOrigin:N.crossOrigin??s.crossOrigin})))}function hM(...a){return i=>{a.forEach(s=>{typeof s=="function"?s(i):s!=null&&(s.current=i)})}}var dM=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{dM&&(window.__reactRouterVersion="7.13.1")}catch{}function mM({basename:a,children:i,unstable_useTransitions:s,window:u}){let c=M.useRef();c.current==null&&(c.current=kA({window:u,v5Compat:!0}));let h=c.current,[f,m]=M.useState({action:h.action,location:h.location}),y=M.useCallback(p=>{s===!1?m(p):M.startTransition(()=>m(p))},[s]);return M.useLayoutEffect(()=>h.listen(y),[h,y]),M.createElement(X2,{basename:a,children:i,location:f.location,navigationType:f.action,navigator:h,unstable_useTransitions:s})}var v0=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Si=M.forwardRef(function({onClick:i,discover:s="render",prefetch:u="none",relative:c,reloadDocument:h,replace:f,unstable_mask:m,state:y,target:p,to:g,preventScrollReset:S,viewTransition:b,unstable_defaultShouldRevalidate:A,...D},V){let{basename:N,navigator:O,unstable_useTransitions:G}=M.useContext(qe),B=typeof g=="string"&&v0.test(g),Q=u0(g,N);g=Q.to;let X=D2(g,{relative:c}),tt=Dn(),J=null;if(m){let Vt=Of(m,[],tt.unstable_mask?tt.unstable_mask.pathname:"/",!0);N!=="/"&&(Vt.pathname=Vt.pathname==="/"?N:tn([N,Vt.pathname])),J=O.createHref(Vt)}let[k,at,St]=rM(u,D),wt=vM(g,{replace:f,unstable_mask:m,state:y,target:p,preventScrollReset:S,relative:c,viewTransition:b,unstable_defaultShouldRevalidate:A,unstable_useTransitions:G});function Ut(Vt){i&&i(Vt),Vt.defaultPrevented||wt(Vt)}let ce=!(Q.isExternal||h),le=M.createElement("a",{...D,...St,href:(ce?J:void 0)||Q.absoluteURL||X,onClick:ce?Ut:i,ref:hM(V,at),target:p,"data-discover":!B&&s==="render"?"true":void 0});return k&&!B?M.createElement(M.Fragment,null,le,M.createElement(oM,{page:X})):le});Si.displayName="Link";var pM=M.forwardRef(function({"aria-current":i="page",caseSensitive:s=!1,className:u="",end:c=!1,style:h,to:f,viewTransition:m,children:y,...p},g){let S=ql(f,{relative:p.relative}),b=Dn(),A=M.useContext(wu),{navigator:D,basename:V}=M.useContext(qe),N=A!=null&&EM(S)&&m===!0,O=D.encodeLocation?D.encodeLocation(S).pathname:S.pathname,G=b.pathname,B=A&&A.navigation&&A.navigation.location?A.navigation.location.pathname:null;s||(G=G.toLowerCase(),B=B?B.toLowerCase():null,O=O.toLowerCase()),B&&V&&(B=Mn(B,V)||B);const Q=O!=="/"&&O.endsWith("/")?O.length-1:O.length;let X=G===O||!c&&G.startsWith(O)&&G.charAt(Q)==="/",tt=B!=null&&(B===O||!c&&B.startsWith(O)&&B.charAt(O.length)==="/"),J={isActive:X,isPending:tt,isTransitioning:N},k=X?i:void 0,at;typeof u=="function"?at=u(J):at=[u,X?"active":null,tt?"pending":null,N?"transitioning":null].filter(Boolean).join(" ");let St=typeof h=="function"?h(J):h;return M.createElement(Si,{...p,"aria-current":k,className:at,ref:g,style:St,to:f,viewTransition:m},typeof y=="function"?y(J):y)});pM.displayName="NavLink";var yM=M.forwardRef(({discover:a="render",fetcherKey:i,navigate:s,reloadDocument:u,replace:c,state:h,method:f=yu,action:m,onSubmit:y,relative:p,preventScrollReset:g,viewTransition:S,unstable_defaultShouldRevalidate:b,...A},D)=>{let{unstable_useTransitions:V}=M.useContext(qe),N=xM(),O=TM(m,{relative:p}),G=f.toLowerCase()==="get"?"get":"post",B=typeof m=="string"&&v0.test(m),Q=X=>{if(y&&y(X),X.defaultPrevented)return;X.preventDefault();let tt=X.nativeEvent.submitter,J=(tt==null?void 0:tt.getAttribute("formmethod"))||f,k=()=>N(tt||X.currentTarget,{fetcherKey:i,method:J,navigate:s,replace:c,state:h,relative:p,preventScrollReset:g,viewTransition:S,unstable_defaultShouldRevalidate:b});V&&s!==!1?M.startTransition(()=>k()):k()};return M.createElement("form",{ref:D,method:G,action:O,onSubmit:u?y:Q,...A,"data-discover":!B&&a==="render"?"true":void 0})});yM.displayName="Form";function gM(a){return`${a} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function S0(a){let i=M.useContext(Mi);return _t(i,gM(a)),i}function vM(a,{target:i,replace:s,unstable_mask:u,state:c,preventScrollReset:h,relative:f,viewTransition:m,unstable_defaultShouldRevalidate:y,unstable_useTransitions:p}={}){let g=C2(),S=Dn(),b=ql(a,{relative:f});return M.useCallback(A=>{if(F2(A,i)){A.preventDefault();let D=s!==void 0?s:Nl(S)===Nl(b),V=()=>g(a,{replace:D,unstable_mask:u,state:c,preventScrollReset:h,relative:f,viewTransition:m,unstable_defaultShouldRevalidate:y});p?M.startTransition(()=>V()):V()}},[S,g,b,s,u,c,i,a,h,f,m,y,p])}var SM=0,bM=()=>`__${String(++SM)}__`;function xM(){let{router:a}=S0("useSubmit"),{basename:i}=M.useContext(qe),s=H2(),u=a.fetch,c=a.navigate;return M.useCallback(async(h,f={})=>{let{action:m,method:y,encType:p,formData:g,body:S}=$2(h,i);if(f.navigate===!1){let b=f.fetcherKey||bM();await u(b,s,f.action||m,{unstable_defaultShouldRevalidate:f.unstable_defaultShouldRevalidate,preventScrollReset:f.preventScrollReset,formData:g,body:S,formMethod:f.method||y,formEncType:f.encType||p,flushSync:f.flushSync})}else await c(f.action||m,{unstable_defaultShouldRevalidate:f.unstable_defaultShouldRevalidate,preventScrollReset:f.preventScrollReset,formData:g,body:S,formMethod:f.method||y,formEncType:f.encType||p,replace:f.replace,state:f.state,fromRouteId:s,flushSync:f.flushSync,viewTransition:f.viewTransition})},[u,c,i,s])}function TM(a,{relative:i}={}){let{basename:s}=M.useContext(qe),u=M.useContext(Rn);_t(u,"useFormAction must be used inside a RouteContext");let[c]=u.matches.slice(-1),h={...ql(a||".",{relative:i})},f=Dn();if(a==null){h.search=f.search;let m=new URLSearchParams(h.search),y=m.getAll("index");if(y.some(g=>g==="")){m.delete("index"),y.filter(S=>S).forEach(S=>m.append("index",S));let g=m.toString();h.search=g?`?${g}`:""}}return(!a||a===".")&&c.route.index&&(h.search=h.search?h.search.replace(/^\?/,"?index&"):"?index"),s!=="/"&&(h.pathname=h.pathname==="/"?s:tn([s,h.pathname])),Nl(h)}function EM(a,{relative:i}={}){let s=M.useContext(o0);_t(s!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:u}=S0("useViewTransitionState"),c=ql(a,{relative:i});if(!s.isTransitioning)return!1;let h=Mn(s.currentLocation.pathname,u)||s.currentLocation.pathname,f=Mn(s.nextLocation.pathname,u)||s.nextLocation.pathname;return Ru(c.pathname,f)!=null||Ru(c.pathname,h)!=null}const En={hidden:{opacity:0,y:10},visible:{opacity:1,y:0,transition:{duration:.8,ease:[.16,1,.3,1]}},exit:{opacity:0,y:-10,transition:{duration:.3,ease:[.16,1,.3,1]}}};function AM(){const[a,i]=M.useState(!1),s=async()=>{await navigator.clipboard.writeText("npx quark-daemon install-service"),i(!0),setTimeout(()=>i(!1),2e3)};return H.jsxs("div",{className:"flex flex-col gap-32",children:[H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,className:"space-y-8",children:[H.jsx("h1",{className:"text-2xl font-medium tracking-tight text-black",children:"the clipboard is broken."}),H.jsxs("div",{className:"space-y-6 text-lg text-zinc-500 leading-relaxed tracking-tight",children:[H.jsx("p",{children:"you copy text from a pdf. the line breaks shatter."}),H.jsx("p",{children:"you copy a link. tracking tags follow you."}),H.jsx("p",{children:"you copy a table. the formatting vanishes."}),H.jsx("p",{children:"you switch to your laptop. your clipboard is empty."}),H.jsx("p",{children:"it is a fundamental tool, yet it remains fundamentally flawed."})]})]}),H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,transition:{delay:.1},className:"space-y-8",children:[H.jsx("h2",{className:"text-2xl font-medium tracking-tight text-black",children:"enter quark."}),H.jsxs("div",{className:"space-y-6 text-lg text-zinc-500 leading-relaxed tracking-tight",children:[H.jsx("p",{children:"a silent, zero-configuration daemon that lives in your background. it requires no interface. it simply fixes what is broken."}),H.jsxs("ul",{className:"space-y-4 list-none p-0",children:[H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," heals broken pdf text automatically."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," strips tracking parameters from urls."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," transforms raw excel data into clean html tables."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," converts markdown tables and latex formulas into rich html."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," applies smart typographic quotes and normalizes shouted all-caps text."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," syncs across your mac, windows, and linux machines instantly via p2p."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," exposes your clipboard to local ai models via mcp."]})]})]})]}),H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,transition:{delay:.2},className:"space-y-8",children:[H.jsx("h2",{className:"text-2xl font-medium tracking-tight text-black",children:"installation."}),H.jsxs("div",{className:"bg-[#fafafa] rounded-2xl p-8 md:p-12 border border-zinc-100",children:[H.jsx("pre",{className:"font-mono text-xs text-zinc-300 mb-12 leading-tight tracking-widest select-none",children:` o-------o
|
|
68
|
+
Please change the parent <Route path="${O}"> to <Route path="${O==="/"?"*":`${O}/*`}">.`)}let g=Dn(),S;if(i){let O=typeof i=="string"?Ai(i):i;_t(y==="/"||((N=O.pathname)==null?void 0:N.startsWith(y)),`When overriding the location using \`<Routes location>\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${y}" but pathname "${O.pathname}" was given in the \`location\` prop.`),S=O}else S=g;let b=S.pathname||"/",A=b;if(y!=="/"){let O=y.replace(/^\//,"").split("/");A="/"+b.replace(/^\//,"").split("/").slice(O.length).join("/")}let D=n0(a,{pathname:A});nn(p||D!=null,`No routes matched location "${S.pathname}${S.search}${S.hash}" `),nn(D==null||D[D.length-1].route.element!==void 0||D[D.length-1].route.Component!==void 0||D[D.length-1].route.lazy!==void 0,`Matched leaf route at location "${S.pathname}${S.search}${S.hash}" does not have an element or Component. This means it will render an <Outlet /> with a null value by default resulting in an "empty" page.`);let V=U2(D&&D.map(O=>Object.assign({},O,{params:Object.assign({},f,O.params),pathname:tn([y,u.encodeLocation?u.encodeLocation(O.pathname.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:O.pathname]),pathnameBase:O.pathnameBase==="/"?y:tn([y,u.encodeLocation?u.encodeLocation(O.pathnameBase.replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:O.pathnameBase])})),c,s);return i&&V?M.createElement(Ll.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",unstable_mask:void 0,...S},navigationType:"POP"}},V):V}function w2(){let a=q2(),i=g2(a)?`${a.status} ${a.statusText}`:a instanceof Error?a.message:JSON.stringify(a),s=a instanceof Error?a.stack:null,u="rgba(200,200,200, 0.5)",c={padding:"0.5rem",backgroundColor:u},h={padding:"2px 4px",backgroundColor:u},f=null;return console.error("Error handled by React Router default ErrorBoundary:",a),f=M.createElement(M.Fragment,null,M.createElement("p",null,"💿 Hey developer 👋"),M.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",M.createElement("code",{style:h},"ErrorBoundary")," or"," ",M.createElement("code",{style:h},"errorElement")," prop on your route.")),M.createElement(M.Fragment,null,M.createElement("h2",null,"Unexpected Application Error!"),M.createElement("h3",{style:{fontStyle:"italic"}},i),s?M.createElement("pre",{style:c},s):null,f)}var V2=M.createElement(w2,null),m0=class extends M.Component{constructor(a){super(a),this.state={location:a.location,revalidation:a.revalidation,error:a.error}}static getDerivedStateFromError(a){return{error:a}}static getDerivedStateFromProps(a,i){return i.location!==a.location||i.revalidation!=="idle"&&a.revalidation==="idle"?{error:a.error,location:a.location,revalidation:a.revalidation}:{error:a.error!==void 0?a.error:i.error,location:i.location,revalidation:a.revalidation||i.revalidation}}componentDidCatch(a,i){this.props.onError?this.props.onError(a,i):console.error("React Router caught the following error during render",a)}render(){let a=this.state.error;if(this.context&&typeof a=="object"&&a&&"digest"in a&&typeof a.digest=="string"){const s=R2(a.digest);s&&(a=s)}let i=a!==void 0?M.createElement(Rn.Provider,{value:this.props.routeContext},M.createElement(wf.Provider,{value:a,children:this.props.component})):this.props.children;return this.context?M.createElement(N2,{error:a},i):i}};m0.contextType=b2;var Tc=new WeakMap;function N2({children:a,error:i}){let{basename:s}=M.useContext(qe);if(typeof i=="object"&&i&&"digest"in i&&typeof i.digest=="string"){let u=M2(i.digest);if(u){let c=Tc.get(i);if(c)throw c;let h=u0(u.location,s);if(s0&&!Tc.get(i))if(h.isExternal||u.reloadDocument)window.location.href=h.absoluteURL||h.to;else{const f=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(h.to,{replace:u.replace}));throw Tc.set(i,f),f}return M.createElement("meta",{httpEquiv:"refresh",content:`0;url=${h.absoluteURL||h.to}`})}}return a}function _2({routeContext:a,match:i,children:s}){let u=M.useContext(Mi);return u&&u.static&&u.staticContext&&(i.route.errorElement||i.route.ErrorBoundary)&&(u.staticContext._deepestRenderedBoundaryId=i.route.id),M.createElement(Rn.Provider,{value:a},s)}function U2(a,i=[],s){let u=s==null?void 0:s.state;if(a==null){if(!u)return null;if(u.errors)a=u.matches;else if(i.length===0&&!u.initialized&&u.matches.length>0)a=u.matches;else return null}let c=a,h=u==null?void 0:u.errors;if(h!=null){let g=c.findIndex(S=>S.route.id&&(h==null?void 0:h[S.route.id])!==void 0);_t(g>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(h).join(",")}`),c=c.slice(0,Math.min(c.length,g+1))}let f=!1,m=-1;if(s&&u){f=u.renderFallback;for(let g=0;g<c.length;g++){let S=c[g];if((S.route.HydrateFallback||S.route.hydrateFallbackElement)&&(m=g),S.route.id){let{loaderData:b,errors:A}=u,D=S.route.loader&&!b.hasOwnProperty(S.route.id)&&(!A||A[S.route.id]===void 0);if(S.route.lazy||D){s.isStatic&&(f=!0),m>=0?c=c.slice(0,m+1):c=[c[0]];break}}}}let y=s==null?void 0:s.onError,p=u&&y?(g,S)=>{var b,A;y(g,{location:u.location,params:((A=(b=u.matches)==null?void 0:b[0])==null?void 0:A.params)??{},unstable_pattern:v2(u.matches),errorInfo:S})}:void 0;return c.reduceRight((g,S,b)=>{let A,D=!1,V=null,N=null;u&&(A=h&&S.route.id?h[S.route.id]:void 0,V=S.route.errorElement||V2,f&&(m<0&&b===0?(p0("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),D=!0,N=null):m===b&&(D=!0,N=S.route.hydrateFallbackElement||null)));let O=i.concat(c.slice(0,b+1)),G=()=>{let B;return A?B=V:D?B=N:S.route.Component?B=M.createElement(S.route.Component,null):S.route.element?B=S.route.element:B=g,M.createElement(_2,{match:S,routeContext:{outlet:g,matches:O,isDataRoute:u!=null},children:B})};return u&&(S.route.ErrorBoundary||S.route.errorElement||b===0)?M.createElement(m0,{location:u.location,revalidation:u.revalidation,component:V,error:A,children:G(),routeContext:{outlet:null,matches:O,isDataRoute:!0},onError:p}):G()},null)}function Vf(a){return`${a} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function j2(a){let i=M.useContext(Mi);return _t(i,Vf(a)),i}function B2(a){let i=M.useContext(wu);return _t(i,Vf(a)),i}function L2(a){let i=M.useContext(Rn);return _t(i,Vf(a)),i}function Nf(a){let i=L2(a),s=i.matches[i.matches.length-1];return _t(s.route.id,`${a} can only be used on routes that contain a unique "id"`),s.route.id}function H2(){return Nf("useRouteId")}function q2(){var u;let a=M.useContext(wf),i=B2("useRouteError"),s=Nf("useRouteError");return a!==void 0?a:(u=i.errors)==null?void 0:u[s]}function Y2(){let{router:a}=j2("useNavigate"),i=Nf("useNavigate"),s=M.useRef(!1);return h0(()=>{s.current=!0}),M.useCallback(async(c,h={})=>{nn(s.current,f0),s.current&&(typeof c=="number"?await a.navigate(c):await a.navigate(c,{fromRouteId:i,...h}))},[a,i])}var mg={};function p0(a,i,s){!i&&!mg[a]&&(mg[a]=!0,nn(!1,s))}M.memo(G2);function G2({routes:a,future:i,state:s,isStatic:u,onError:c}){return d0(a,void 0,{state:s,isStatic:u,onError:c})}function Fc(a){_t(!1,"A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.")}function X2({basename:a="/",children:i=null,location:s,navigationType:u="POP",navigator:c,static:h=!1,unstable_useTransitions:f}){_t(!Hl(),"You cannot render a <Router> inside another <Router>. You should never have more than one in your app.");let m=a.replace(/^\/*/,"/"),y=M.useMemo(()=>({basename:m,navigator:c,static:h,unstable_useTransitions:f,future:{}}),[m,c,h,f]);typeof s=="string"&&(s=Ai(s));let{pathname:p="/",search:g="",hash:S="",state:b=null,key:A="default",unstable_mask:D}=s,V=M.useMemo(()=>{let N=Mn(p,m);return N==null?null:{location:{pathname:N,search:g,hash:S,state:b,key:A,unstable_mask:D},navigationType:u}},[m,p,g,S,b,A,u,D]);return nn(V!=null,`<Router basename="${m}"> is not able to match the URL "${p}${g}${S}" because it does not start with the basename, so the <Router> won't render anything.`),V==null?null:M.createElement(qe.Provider,{value:y},M.createElement(Ll.Provider,{children:i,value:V}))}function K2({children:a,location:i}){return O2(Pc(a),i)}function Pc(a,i=[]){let s=[];return M.Children.forEach(a,(u,c)=>{if(!M.isValidElement(u))return;let h=[...i,c];if(u.type===M.Fragment){s.push.apply(s,Pc(u.props.children,h));return}_t(u.type===Fc,`[${typeof u.type=="string"?u.type:u.type.name}] is not a <Route> component. All component children of <Routes> must be a <Route> or <React.Fragment>`),_t(!u.props.index||!u.props.children,"An index route cannot have child routes.");let f={id:u.props.id||h.join("-"),caseSensitive:u.props.caseSensitive,element:u.props.element,Component:u.props.Component,index:u.props.index,path:u.props.path,middleware:u.props.middleware,loader:u.props.loader,action:u.props.action,hydrateFallbackElement:u.props.hydrateFallbackElement,HydrateFallback:u.props.HydrateFallback,errorElement:u.props.errorElement,ErrorBoundary:u.props.ErrorBoundary,hasErrorBoundary:u.props.hasErrorBoundary===!0||u.props.ErrorBoundary!=null||u.props.errorElement!=null,shouldRevalidate:u.props.shouldRevalidate,handle:u.props.handle,lazy:u.props.lazy};u.props.children&&(f.children=Pc(u.props.children,h)),s.push(f)}),s}var yu="get",gu="application/x-www-form-urlencoded";function Vu(a){return typeof HTMLElement<"u"&&a instanceof HTMLElement}function Q2(a){return Vu(a)&&a.tagName.toLowerCase()==="button"}function Z2(a){return Vu(a)&&a.tagName.toLowerCase()==="form"}function k2(a){return Vu(a)&&a.tagName.toLowerCase()==="input"}function J2(a){return!!(a.metaKey||a.altKey||a.ctrlKey||a.shiftKey)}function F2(a,i){return a.button===0&&(!i||i==="_self")&&!J2(a)}var ou=null;function P2(){if(ou===null)try{new FormData(document.createElement("form"),0),ou=!1}catch{ou=!0}return ou}var W2=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Ec(a){return a!=null&&!W2.has(a)?(nn(!1,`"${a}" is not a valid \`encType\` for \`<Form>\`/\`<fetcher.Form>\` and will default to "${gu}"`),null):a}function $2(a,i){let s,u,c,h,f;if(Z2(a)){let m=a.getAttribute("action");u=m?Mn(m,i):null,s=a.getAttribute("method")||yu,c=Ec(a.getAttribute("enctype"))||gu,h=new FormData(a)}else if(Q2(a)||k2(a)&&(a.type==="submit"||a.type==="image")){let m=a.form;if(m==null)throw new Error('Cannot submit a <button> or <input type="submit"> without a <form>');let y=a.getAttribute("formaction")||m.getAttribute("action");if(u=y?Mn(y,i):null,s=a.getAttribute("formmethod")||m.getAttribute("method")||yu,c=Ec(a.getAttribute("formenctype"))||Ec(m.getAttribute("enctype"))||gu,h=new FormData(m,a),!P2()){let{name:p,type:g,value:S}=a;if(g==="image"){let b=p?`${p}.`:"";h.append(`${b}x`,"0"),h.append(`${b}y`,"0")}else p&&h.append(p,S)}}else{if(Vu(a))throw new Error('Cannot submit element that is not <form>, <button>, or <input type="submit|image">');s=yu,u=null,c=gu,f=a}return h&&c==="text/plain"&&(f=h,h=void 0),{action:u,method:s.toLowerCase(),encType:c,formData:h,body:f}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");function _f(a,i){if(a===!1||a===null||typeof a>"u")throw new Error(i)}function I2(a,i,s,u){let c=typeof a=="string"?new URL(a,typeof window>"u"?"server://singlefetch/":window.location.origin):a;return s?c.pathname.endsWith("/")?c.pathname=`${c.pathname}_.${u}`:c.pathname=`${c.pathname}.${u}`:c.pathname==="/"?c.pathname=`_root.${u}`:i&&Mn(c.pathname,i)==="/"?c.pathname=`${i.replace(/\/$/,"")}/_root.${u}`:c.pathname=`${c.pathname.replace(/\/$/,"")}.${u}`,c}async function tM(a,i){if(a.id in i)return i[a.id];try{let s=await import(a.module);return i[a.id]=s,s}catch(s){return console.error(`Error loading route module \`${a.module}\`, reloading page...`),console.error(s),window.__reactRouterContext&&window.__reactRouterContext.isSpaMode,window.location.reload(),new Promise(()=>{})}}function eM(a){return a==null?!1:a.href==null?a.rel==="preload"&&typeof a.imageSrcSet=="string"&&typeof a.imageSizes=="string":typeof a.rel=="string"&&typeof a.href=="string"}async function nM(a,i,s){let u=await Promise.all(a.map(async c=>{let h=i.routes[c.route.id];if(h){let f=await tM(h,s);return f.links?f.links():[]}return[]}));return sM(u.flat(1).filter(eM).filter(c=>c.rel==="stylesheet"||c.rel==="preload").map(c=>c.rel==="stylesheet"?{...c,rel:"prefetch",as:"style"}:{...c,rel:"prefetch"}))}function pg(a,i,s,u,c,h){let f=(y,p)=>s[p]?y.route.id!==s[p].route.id:!0,m=(y,p)=>{var g;return s[p].pathname!==y.pathname||((g=s[p].route.path)==null?void 0:g.endsWith("*"))&&s[p].params["*"]!==y.params["*"]};return h==="assets"?i.filter((y,p)=>f(y,p)||m(y,p)):h==="data"?i.filter((y,p)=>{var S;let g=u.routes[y.route.id];if(!g||!g.hasLoader)return!1;if(f(y,p)||m(y,p))return!0;if(y.route.shouldRevalidate){let b=y.route.shouldRevalidate({currentUrl:new URL(c.pathname+c.search+c.hash,window.origin),currentParams:((S=s[0])==null?void 0:S.params)||{},nextUrl:new URL(a,window.origin),nextParams:y.params,defaultShouldRevalidate:!0});if(typeof b=="boolean")return b}return!0}):[]}function aM(a,i,{includeHydrateFallback:s}={}){return iM(a.map(u=>{let c=i.routes[u.route.id];if(!c)return[];let h=[c.module];return c.clientActionModule&&(h=h.concat(c.clientActionModule)),c.clientLoaderModule&&(h=h.concat(c.clientLoaderModule)),s&&c.hydrateFallbackModule&&(h=h.concat(c.hydrateFallbackModule)),c.imports&&(h=h.concat(c.imports)),h}).flat(1))}function iM(a){return[...new Set(a)]}function lM(a){let i={},s=Object.keys(a).sort();for(let u of s)i[u]=a[u];return i}function sM(a,i){let s=new Set;return new Set(i),a.reduce((u,c)=>{let h=JSON.stringify(lM(c));return s.has(h)||(s.add(h),u.push({key:h,link:c})),u},[])}function y0(){let a=M.useContext(Mi);return _f(a,"You must render this element inside a <DataRouterContext.Provider> element"),a}function uM(){let a=M.useContext(wu);return _f(a,"You must render this element inside a <DataRouterStateContext.Provider> element"),a}var Uf=M.createContext(void 0);Uf.displayName="FrameworkContext";function g0(){let a=M.useContext(Uf);return _f(a,"You must render this element inside a <HydratedRouter> element"),a}function rM(a,i){let s=M.useContext(Uf),[u,c]=M.useState(!1),[h,f]=M.useState(!1),{onFocus:m,onBlur:y,onMouseEnter:p,onMouseLeave:g,onTouchStart:S}=i,b=M.useRef(null);M.useEffect(()=>{if(a==="render"&&f(!0),a==="viewport"){let V=O=>{O.forEach(G=>{f(G.isIntersecting)})},N=new IntersectionObserver(V,{threshold:.5});return b.current&&N.observe(b.current),()=>{N.disconnect()}}},[a]),M.useEffect(()=>{if(u){let V=setTimeout(()=>{f(!0)},100);return()=>{clearTimeout(V)}}},[u]);let A=()=>{c(!0)},D=()=>{c(!1),f(!1)};return s?a!=="intent"?[h,b,{}]:[h,b,{onFocus:Tl(m,A),onBlur:Tl(y,D),onMouseEnter:Tl(p,A),onMouseLeave:Tl(g,D),onTouchStart:Tl(S,A)}]:[!1,b,{}]}function Tl(a,i){return s=>{a&&a(s),s.defaultPrevented||i(s)}}function oM({page:a,...i}){let{router:s}=y0(),u=M.useMemo(()=>n0(s.routes,a,s.basename),[s.routes,a,s.basename]);return u?M.createElement(fM,{page:a,matches:u,...i}):null}function cM(a){let{manifest:i,routeModules:s}=g0(),[u,c]=M.useState([]);return M.useEffect(()=>{let h=!1;return nM(a,i,s).then(f=>{h||c(f)}),()=>{h=!0}},[a,i,s]),u}function fM({page:a,matches:i,...s}){let u=Dn(),{future:c,manifest:h,routeModules:f}=g0(),{basename:m}=y0(),{loaderData:y,matches:p}=uM(),g=M.useMemo(()=>pg(a,i,p,h,u,"data"),[a,i,p,h,u]),S=M.useMemo(()=>pg(a,i,p,h,u,"assets"),[a,i,p,h,u]),b=M.useMemo(()=>{if(a===u.pathname+u.search+u.hash)return[];let V=new Set,N=!1;if(i.forEach(G=>{var Q;let B=h.routes[G.route.id];!B||!B.hasLoader||(!g.some(X=>X.route.id===G.route.id)&&G.route.id in y&&((Q=f[G.route.id])!=null&&Q.shouldRevalidate)||B.hasClientLoader?N=!0:V.add(G.route.id))}),V.size===0)return[];let O=I2(a,m,c.unstable_trailingSlashAwareDataRequests,"data");return N&&V.size>0&&O.searchParams.set("_routes",i.filter(G=>V.has(G.route.id)).map(G=>G.route.id).join(",")),[O.pathname+O.search]},[m,c.unstable_trailingSlashAwareDataRequests,y,u,h,g,i,a,f]),A=M.useMemo(()=>aM(S,h),[S,h]),D=cM(S);return M.createElement(M.Fragment,null,b.map(V=>M.createElement("link",{key:V,rel:"prefetch",as:"fetch",href:V,...s})),A.map(V=>M.createElement("link",{key:V,rel:"modulepreload",href:V,...s})),D.map(({key:V,link:N})=>M.createElement("link",{key:V,nonce:s.nonce,...N,crossOrigin:N.crossOrigin??s.crossOrigin})))}function hM(...a){return i=>{a.forEach(s=>{typeof s=="function"?s(i):s!=null&&(s.current=i)})}}var dM=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";try{dM&&(window.__reactRouterVersion="7.13.1")}catch{}function mM({basename:a,children:i,unstable_useTransitions:s,window:u}){let c=M.useRef();c.current==null&&(c.current=kA({window:u,v5Compat:!0}));let h=c.current,[f,m]=M.useState({action:h.action,location:h.location}),y=M.useCallback(p=>{s===!1?m(p):M.startTransition(()=>m(p))},[s]);return M.useLayoutEffect(()=>h.listen(y),[h,y]),M.createElement(X2,{basename:a,children:i,location:f.location,navigationType:f.action,navigator:h,unstable_useTransitions:s})}var v0=/^(?:[a-z][a-z0-9+.-]*:|\/\/)/i,Si=M.forwardRef(function({onClick:i,discover:s="render",prefetch:u="none",relative:c,reloadDocument:h,replace:f,unstable_mask:m,state:y,target:p,to:g,preventScrollReset:S,viewTransition:b,unstable_defaultShouldRevalidate:A,...D},V){let{basename:N,navigator:O,unstable_useTransitions:G}=M.useContext(qe),B=typeof g=="string"&&v0.test(g),Q=u0(g,N);g=Q.to;let X=D2(g,{relative:c}),tt=Dn(),J=null;if(m){let Vt=Of(m,[],tt.unstable_mask?tt.unstable_mask.pathname:"/",!0);N!=="/"&&(Vt.pathname=Vt.pathname==="/"?N:tn([N,Vt.pathname])),J=O.createHref(Vt)}let[k,at,St]=rM(u,D),wt=vM(g,{replace:f,unstable_mask:m,state:y,target:p,preventScrollReset:S,relative:c,viewTransition:b,unstable_defaultShouldRevalidate:A,unstable_useTransitions:G});function Ut(Vt){i&&i(Vt),Vt.defaultPrevented||wt(Vt)}let ce=!(Q.isExternal||h),le=M.createElement("a",{...D,...St,href:(ce?J:void 0)||Q.absoluteURL||X,onClick:ce?Ut:i,ref:hM(V,at),target:p,"data-discover":!B&&s==="render"?"true":void 0});return k&&!B?M.createElement(M.Fragment,null,le,M.createElement(oM,{page:X})):le});Si.displayName="Link";var pM=M.forwardRef(function({"aria-current":i="page",caseSensitive:s=!1,className:u="",end:c=!1,style:h,to:f,viewTransition:m,children:y,...p},g){let S=ql(f,{relative:p.relative}),b=Dn(),A=M.useContext(wu),{navigator:D,basename:V}=M.useContext(qe),N=A!=null&&EM(S)&&m===!0,O=D.encodeLocation?D.encodeLocation(S).pathname:S.pathname,G=b.pathname,B=A&&A.navigation&&A.navigation.location?A.navigation.location.pathname:null;s||(G=G.toLowerCase(),B=B?B.toLowerCase():null,O=O.toLowerCase()),B&&V&&(B=Mn(B,V)||B);const Q=O!=="/"&&O.endsWith("/")?O.length-1:O.length;let X=G===O||!c&&G.startsWith(O)&&G.charAt(Q)==="/",tt=B!=null&&(B===O||!c&&B.startsWith(O)&&B.charAt(O.length)==="/"),J={isActive:X,isPending:tt,isTransitioning:N},k=X?i:void 0,at;typeof u=="function"?at=u(J):at=[u,X?"active":null,tt?"pending":null,N?"transitioning":null].filter(Boolean).join(" ");let St=typeof h=="function"?h(J):h;return M.createElement(Si,{...p,"aria-current":k,className:at,ref:g,style:St,to:f,viewTransition:m},typeof y=="function"?y(J):y)});pM.displayName="NavLink";var yM=M.forwardRef(({discover:a="render",fetcherKey:i,navigate:s,reloadDocument:u,replace:c,state:h,method:f=yu,action:m,onSubmit:y,relative:p,preventScrollReset:g,viewTransition:S,unstable_defaultShouldRevalidate:b,...A},D)=>{let{unstable_useTransitions:V}=M.useContext(qe),N=xM(),O=TM(m,{relative:p}),G=f.toLowerCase()==="get"?"get":"post",B=typeof m=="string"&&v0.test(m),Q=X=>{if(y&&y(X),X.defaultPrevented)return;X.preventDefault();let tt=X.nativeEvent.submitter,J=(tt==null?void 0:tt.getAttribute("formmethod"))||f,k=()=>N(tt||X.currentTarget,{fetcherKey:i,method:J,navigate:s,replace:c,state:h,relative:p,preventScrollReset:g,viewTransition:S,unstable_defaultShouldRevalidate:b});V&&s!==!1?M.startTransition(()=>k()):k()};return M.createElement("form",{ref:D,method:G,action:O,onSubmit:u?y:Q,...A,"data-discover":!B&&a==="render"?"true":void 0})});yM.displayName="Form";function gM(a){return`${a} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function S0(a){let i=M.useContext(Mi);return _t(i,gM(a)),i}function vM(a,{target:i,replace:s,unstable_mask:u,state:c,preventScrollReset:h,relative:f,viewTransition:m,unstable_defaultShouldRevalidate:y,unstable_useTransitions:p}={}){let g=C2(),S=Dn(),b=ql(a,{relative:f});return M.useCallback(A=>{if(F2(A,i)){A.preventDefault();let D=s!==void 0?s:Nl(S)===Nl(b),V=()=>g(a,{replace:D,unstable_mask:u,state:c,preventScrollReset:h,relative:f,viewTransition:m,unstable_defaultShouldRevalidate:y});p?M.startTransition(()=>V()):V()}},[S,g,b,s,u,c,i,a,h,f,m,y,p])}var SM=0,bM=()=>`__${String(++SM)}__`;function xM(){let{router:a}=S0("useSubmit"),{basename:i}=M.useContext(qe),s=H2(),u=a.fetch,c=a.navigate;return M.useCallback(async(h,f={})=>{let{action:m,method:y,encType:p,formData:g,body:S}=$2(h,i);if(f.navigate===!1){let b=f.fetcherKey||bM();await u(b,s,f.action||m,{unstable_defaultShouldRevalidate:f.unstable_defaultShouldRevalidate,preventScrollReset:f.preventScrollReset,formData:g,body:S,formMethod:f.method||y,formEncType:f.encType||p,flushSync:f.flushSync})}else await c(f.action||m,{unstable_defaultShouldRevalidate:f.unstable_defaultShouldRevalidate,preventScrollReset:f.preventScrollReset,formData:g,body:S,formMethod:f.method||y,formEncType:f.encType||p,replace:f.replace,state:f.state,fromRouteId:s,flushSync:f.flushSync,viewTransition:f.viewTransition})},[u,c,i,s])}function TM(a,{relative:i}={}){let{basename:s}=M.useContext(qe),u=M.useContext(Rn);_t(u,"useFormAction must be used inside a RouteContext");let[c]=u.matches.slice(-1),h={...ql(a||".",{relative:i})},f=Dn();if(a==null){h.search=f.search;let m=new URLSearchParams(h.search),y=m.getAll("index");if(y.some(g=>g==="")){m.delete("index"),y.filter(S=>S).forEach(S=>m.append("index",S));let g=m.toString();h.search=g?`?${g}`:""}}return(!a||a===".")&&c.route.index&&(h.search=h.search?h.search.replace(/^\?/,"?index&"):"?index"),s!=="/"&&(h.pathname=h.pathname==="/"?s:tn([s,h.pathname])),Nl(h)}function EM(a,{relative:i}={}){let s=M.useContext(o0);_t(s!=null,"`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. Did you accidentally import `RouterProvider` from `react-router`?");let{basename:u}=S0("useViewTransitionState"),c=ql(a,{relative:i});if(!s.isTransitioning)return!1;let h=Mn(s.currentLocation.pathname,u)||s.currentLocation.pathname,f=Mn(s.nextLocation.pathname,u)||s.nextLocation.pathname;return Ru(c.pathname,f)!=null||Ru(c.pathname,h)!=null}const En={hidden:{opacity:0,y:10},visible:{opacity:1,y:0,transition:{duration:.8,ease:[.16,1,.3,1]}},exit:{opacity:0,y:-10,transition:{duration:.3,ease:[.16,1,.3,1]}}};function AM(){const[a,i]=M.useState(!1),s=async()=>{await navigator.clipboard.writeText("npx -y @quark.clip/quark install-service"),i(!0),setTimeout(()=>i(!1),2e3)};return H.jsxs("div",{className:"flex flex-col gap-32",children:[H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,className:"space-y-8",children:[H.jsx("h1",{className:"text-2xl font-medium tracking-tight text-black",children:"the clipboard is broken."}),H.jsxs("div",{className:"space-y-6 text-lg text-zinc-500 leading-relaxed tracking-tight",children:[H.jsx("p",{children:"you copy text from a pdf. the line breaks shatter."}),H.jsx("p",{children:"you copy a link. tracking tags follow you."}),H.jsx("p",{children:"you copy a table. the formatting vanishes."}),H.jsx("p",{children:"you switch to your laptop. your clipboard is empty."}),H.jsx("p",{children:"it is a fundamental tool, yet it remains fundamentally flawed."})]})]}),H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,transition:{delay:.1},className:"space-y-8",children:[H.jsx("h2",{className:"text-2xl font-medium tracking-tight text-black",children:"enter quark."}),H.jsxs("div",{className:"space-y-6 text-lg text-zinc-500 leading-relaxed tracking-tight",children:[H.jsx("p",{children:"a silent, zero-configuration daemon that lives in your background. it requires no interface. it simply fixes what is broken."}),H.jsxs("ul",{className:"space-y-4 list-none p-0",children:[H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," heals broken pdf text automatically."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," strips tracking parameters from urls."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," transforms raw excel data into clean html tables."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," converts markdown tables and latex formulas into rich html."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," applies smart typographic quotes and normalizes shouted all-caps text."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," syncs across your mac, windows, and linux machines instantly via p2p."]}),H.jsxs("li",{className:"flex gap-4",children:[H.jsx("span",{className:"text-zinc-300",children:"—"})," exposes your clipboard to local ai models via mcp."]})]})]})]}),H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,transition:{delay:.2},className:"space-y-8",children:[H.jsx("h2",{className:"text-2xl font-medium tracking-tight text-black",children:"installation."}),H.jsxs("div",{className:"bg-[#fafafa] rounded-2xl p-8 md:p-12 border border-zinc-100",children:[H.jsx("pre",{className:"font-mono text-xs text-zinc-300 mb-12 leading-tight tracking-widest select-none",children:` o-------o
|
|
69
69
|
| \\ / |
|
|
70
70
|
| o |
|
|
71
71
|
| / \\ |
|
|
72
|
-
o-------o`}),H.jsxs("div",{className:"flex flex-col sm:flex-row gap-6 items-start sm:items-center justify-between",children:[H.jsx("code",{className:"font-mono text-sm text-zinc-800 bg-white px-3 py-1.5 rounded-md border border-zinc-200 shadow-sm",children:"npx
|
|
72
|
+
o-------o`}),H.jsxs("div",{className:"flex flex-col sm:flex-row gap-6 items-start sm:items-center justify-between",children:[H.jsx("code",{className:"font-mono text-sm text-zinc-800 bg-white px-3 py-1.5 rounded-md border border-zinc-200 shadow-sm",children:"npx -y @quark.clip/quark install-service"}),H.jsx("button",{onClick:s,className:"text-sm font-medium text-zinc-400 hover:text-black transition-colors",children:a?"copied.":"copy command."})]})]}),H.jsxs("p",{className:"text-sm text-zinc-400 tracking-tight",children:["requires node.js. runs silently on mac, windows, and linux. open source. ",H.jsx(Si,{to:"/docs",className:"text-black hover:underline",children:"read the docs."})]})]})]})}function MM(){return H.jsxs("div",{className:"flex flex-col gap-24",children:[H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,className:"space-y-8",children:[H.jsx("h1",{className:"text-2xl font-medium tracking-tight text-black",children:"knowledge base."}),H.jsx("p",{className:"text-lg text-zinc-500 leading-relaxed tracking-tight",children:"everything you need to know about how quark operates under the hood."})]}),H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,transition:{delay:.1},className:"space-y-6",children:[H.jsx("h2",{className:"text-xl font-medium tracking-tight text-black",children:"1. the pipeline"}),H.jsxs("div",{className:"space-y-4 text-zinc-500 leading-relaxed tracking-tight",children:[H.jsx("p",{children:"quark intercepts your clipboard and runs it through a series of smart transformers before syncing or pasting."}),H.jsxs("ul",{className:"space-y-4 mt-4",children:[H.jsxs("li",{children:[H.jsx("strong",{className:"text-zinc-700 font-medium",children:"markdown & latex:"})," detects `$$math$$` and `| tables |` and compiles them into rich html on the fly."]}),H.jsxs("li",{children:[H.jsx("strong",{className:"text-zinc-700 font-medium",children:"excel & csv:"})," raw tab-separated or comma-separated values are instantly converted into styled html tables."]}),H.jsxs("li",{children:[H.jsx("strong",{className:"text-zinc-700 font-medium",children:"url sanitization:"})," automatically strips `utm_source`, `igshid`, and other tracking parameters from copied links."]}),H.jsxs("li",{children:[H.jsx("strong",{className:"text-zinc-700 font-medium",children:"typography:"})," detects language (english, french, german, spanish) and applies the correct smart quotes (« », „ “, “ ”). normalizes all-caps shouting into sentence case."]}),H.jsxs("li",{children:[H.jsx("strong",{className:"text-zinc-700 font-medium",children:"pdf healing:"})," uses heuristics to detect and remove artificial line breaks caused by copying from pdfs."]})]})]})]}),H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,transition:{delay:.2},className:"space-y-6",children:[H.jsx("h2",{className:"text-xl font-medium tracking-tight text-black",children:"2. p2p sync"}),H.jsxs("div",{className:"space-y-4 text-zinc-500 leading-relaxed tracking-tight",children:[H.jsx("p",{children:"quark uses mdns (bonjour/zeroconf) to broadcast its presence on your local wi-fi network."}),H.jsx("p",{children:"when two devices running quark discover each other, they establish a direct websocket connection on port 41235. when you copy on one device, the payload (both plain text and rich html) is instantly pushed to the other."}),H.jsx("p",{children:"there are no cloud servers, no accounts, and no data leaves your local network."})]})]}),H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,transition:{delay:.3},className:"space-y-6",children:[H.jsx("h2",{className:"text-xl font-medium tracking-tight text-black",children:"3. ai integration (mcp)"}),H.jsxs("div",{className:"space-y-4 text-zinc-500 leading-relaxed tracking-tight",children:[H.jsx("p",{children:"quark acts as a model context protocol (mcp) server, allowing local ai agents like claude desktop or cursor to read and write to your clipboard."}),H.jsxs("p",{children:["to connect claude desktop, add this to your ",H.jsx("code",{className:"bg-zinc-100 px-1.5 py-0.5 rounded text-zinc-700 text-sm",children:"claude_desktop_config.json"}),":"]}),H.jsx("pre",{className:"bg-[#fafafa] p-6 rounded-xl border border-zinc-100 text-sm font-mono text-zinc-600 overflow-x-auto",children:`{
|
|
73
73
|
"mcpServers": {
|
|
74
74
|
"quark": {
|
|
75
75
|
"command": "npx",
|
|
76
|
-
"args": ["
|
|
76
|
+
"args": ["-y", "@quark.clip/quark", "mcp"]
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
}`})]})]}),H.jsxs(Tn.section,{initial:"hidden",animate:"visible",exit:"exit",variants:En,transition:{delay:.4},className:"space-y-6",children:[H.jsx("h2",{className:"text-xl font-medium tracking-tight text-black",children:"4. cli reference"}),H.jsxs("div",{className:"space-y-4 text-zinc-500 leading-relaxed tracking-tight",children:[H.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4 border-b border-zinc-100 pb-4",children:[H.jsx("code",{className:"text-sm font-mono text-zinc-800",children:"quark start"}),H.jsx("span",{className:"sm:col-span-2",children:"runs the daemon in the current terminal session."})]}),H.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4 border-b border-zinc-100 pb-4",children:[H.jsx("code",{className:"text-sm font-mono text-zinc-800",children:"quark install"}),H.jsx("span",{className:"sm:col-span-2",children:"installs quark as a native background service (launchd, systemd, or windows startup)."})]}),H.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4 border-b border-zinc-100 pb-4",children:[H.jsx("code",{className:"text-sm font-mono text-zinc-800",children:"quark stop"}),H.jsx("span",{className:"sm:col-span-2",children:"stops a manually started session."})]}),H.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4 border-b border-zinc-100 pb-4",children:[H.jsx("code",{className:"text-sm font-mono text-zinc-800",children:"quark uninstall"}),H.jsx("span",{className:"sm:col-span-2",children:"removes the background service from your os."})]}),H.jsxs("div",{className:"grid grid-cols-1 sm:grid-cols-3 gap-4 border-b border-zinc-100 pb-4",children:[H.jsx("code",{className:"text-sm font-mono text-zinc-800",children:"quark status"}),H.jsx("span",{className:"sm:col-span-2",children:"checks if the daemon is running and shows log locations."})]})]})]})]})}function RM(){const a=Dn();return M.useEffect(()=>{window.scrollTo({top:0,behavior:"smooth"})},[a.pathname]),H.jsxs("div",{className:"min-h-screen bg-white text-zinc-900 font-sans lowercase selection:bg-zinc-200 selection:text-black",children:[H.jsx("nav",{className:"fixed top-0 w-full bg-white/80 backdrop-blur-md z-50 border-b border-zinc-100",children:H.jsxs("div",{className:"max-w-2xl mx-auto px-8 h-16 flex items-center justify-between text-sm tracking-tight",children:[H.jsxs(Si,{to:"/",className:"font-medium text-black hover:text-zinc-500 transition-colors flex items-center gap-2",children:[H.jsx("img",{src:"/quark/logo.svg",alt:"quark logo",className:"w-4 h-4"}),"quark."]}),H.jsxs("div",{className:"flex gap-6",children:[H.jsx(Si,{to:"/",className:`${a.pathname==="/"?"text-black":"text-zinc-400"} hover:text-black transition-colors`,children:"home."}),H.jsx(Si,{to:"/docs",className:`${a.pathname==="/docs"?"text-black":"text-zinc-400"} hover:text-black transition-colors`,children:"docs."}),H.jsx("a",{href:"https://github.com/sir-ad/quark",target:"_blank",rel:"noreferrer",className:"text-zinc-400 hover:text-black transition-colors",children:"github."})]})]})}),H.jsxs("main",{className:"max-w-2xl mx-auto px-8 pt-32 pb-32 md:pt-48",children:[H.jsx(HE,{mode:"wait",children:H.jsxs(K2,{location:a,children:[H.jsx(Fc,{path:"/",element:H.jsx(AM,{})}),H.jsx(Fc,{path:"/docs",element:H.jsx(MM,{})})]},a.pathname)}),H.jsxs(Tn.footer,{initial:"hidden",animate:"visible",variants:En,transition:{delay:.6},className:"pt-16 mt-32 border-t border-zinc-100 text-sm text-zinc-400 tracking-tight flex justify-between",children:[H.jsx("span",{children:"quark daemon."}),H.jsx("span",{children:"© 2026"})]})]})]})}function DM(){return H.jsx(mM,{basename:"/quark",children:H.jsx(RM,{})})}$1.createRoot(document.getElementById("root")).render(H.jsx(M.StrictMode,{children:H.jsx(DM,{})}));
|
package/dist/index.html
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
}
|
|
20
20
|
}(window.location));
|
|
21
21
|
</script>
|
|
22
|
-
<script type="module" crossorigin src="/quark/assets/index-
|
|
22
|
+
<script type="module" crossorigin src="/quark/assets/index-CDMgweEY.js"></script>
|
|
23
23
|
<link rel="stylesheet" crossorigin href="/quark/assets/index-Dn1mbcJe.css">
|
|
24
24
|
</head>
|
|
25
25
|
<body>
|