@snagset/server 0.0.1 → 0.0.2
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/dist/app.js +11 -6
- package/dist/app.js.map +1 -1
- package/dist/reviewerCache.js +34 -0
- package/dist/reviewerCache.js.map +1 -0
- package/dist/routes/auth.js +32 -1
- package/dist/routes/auth.js.map +1 -1
- package/dist/vendor/types/names.js +2 -0
- package/package.json +2 -2
- package/static/dashboard/assets/index-DsUJ96yc.css +1 -0
- package/static/dashboard/assets/index-DultqpS7.js +1 -0
- package/static/dashboard/index.html +3 -2
- package/static/dashboard/mark.svg +25 -0
- package/static/widget/snag.capture.js +3 -3
- package/static/widget/snag.dock.js +5 -5
- package/static/widget/snag.js +3 -3
- package/static/widget/snag.panels.js +2 -2
- package/static/widget/snag.runtime.js +2 -2
- package/static/widget/snag.text.js +2 -2
- package/static/dashboard/assets/index-CaPfKhFP.css +0 -1
- package/static/dashboard/assets/index-DfTNjHCK.js +0 -1
package/dist/app.js
CHANGED
|
@@ -13,6 +13,7 @@ import { commentRoutes } from "./routes/comments.js";
|
|
|
13
13
|
import { commentEditRoutes } from "./routes/commentEdit.js";
|
|
14
14
|
import { corsForProjects } from "./routes/cors.js";
|
|
15
15
|
import { bearerAuth } from "./routes/auth.js";
|
|
16
|
+
import { createReviewerCache } from "./reviewerCache.js";
|
|
16
17
|
import { attachmentRoutes, features } from "./routes/attachments.js";
|
|
17
18
|
import { sessionRoutes } from "./routes/sessions.js";
|
|
18
19
|
import { reviewLinkRoutes } from "./routes/reviewLinks.js";
|
|
@@ -48,6 +49,10 @@ export function createApp(deps) {
|
|
|
48
49
|
// `session_epoch` revocation cost nothing per request (05 §4.4).
|
|
49
50
|
const keys = createKeyring(deps.secretKey, cfg.get("SNAGSET_SECRET_KEY_PREVIOUS"));
|
|
50
51
|
const projects = createProjectCache(sql);
|
|
52
|
+
/** Per-identity revocation, same ten-second window as the project cache
|
|
53
|
+
* (05 §4.6). Its absence is what let a signed-out reviewer keep working
|
|
54
|
+
* until their token refreshed. */
|
|
55
|
+
const reviewers = createReviewerCache(sql);
|
|
51
56
|
const ttls = {
|
|
52
57
|
slidingS: cfg.int("SNAGSET_SESSION_TTL_S"),
|
|
53
58
|
absoluteS: cfg.int("SNAGSET_SESSION_ABSOLUTE_TTL_S"),
|
|
@@ -271,15 +276,15 @@ export function createApp(deps) {
|
|
|
271
276
|
// After CORS, before the routes: a session is ATTACHED when one verifies and
|
|
272
277
|
// the route decides whether it needed one. `/sessions` is excluded — it is
|
|
273
278
|
// where a bearer is exchanged, not presented.
|
|
274
|
-
app.use("/api/v1/projects/:uid/threads", bearerAuth(keys, projects, ttls.absoluteS));
|
|
275
|
-
app.use("/api/v1/projects/:uid/threads/*", bearerAuth(keys, projects, ttls.absoluteS));
|
|
279
|
+
app.use("/api/v1/projects/:uid/threads", bearerAuth(keys, projects, ttls.absoluteS, reviewers));
|
|
280
|
+
app.use("/api/v1/projects/:uid/threads/*", bearerAuth(keys, projects, ttls.absoluteS, reviewers));
|
|
276
281
|
// The dashboard's unscoped form, `/api/v1/threads/{id}/comments` — no `:uid`
|
|
277
282
|
// segment for `bearerAuth` to read, so this mount is a no-op today (it
|
|
278
283
|
// returns immediately whenever its own `uid` param is absent). Added anyway
|
|
279
284
|
// so the credential-attaching middleware for this surface is declared once,
|
|
280
285
|
// per path, the same way every other one here is — not discovered missing
|
|
281
286
|
// the day a bearer-carrying caller of the unscoped form shows up.
|
|
282
|
-
app.use("/api/v1/threads/*", bearerAuth(keys, projects, ttls.absoluteS));
|
|
287
|
+
app.use("/api/v1/threads/*", bearerAuth(keys, projects, ttls.absoluteS, reviewers));
|
|
283
288
|
app.route("/", sessionRoutes({ sql, keys, projects, ttls }));
|
|
284
289
|
// Whether to QUEUE a notification at all — see CommentDeps.notifications.
|
|
285
290
|
// Computed once at construction: the transport cannot change without a
|
|
@@ -293,10 +298,10 @@ export function createApp(deps) {
|
|
|
293
298
|
* session is a legitimate credential on these paths, so `requireOwner()`
|
|
294
299
|
* must not stand in front of them.
|
|
295
300
|
*/
|
|
296
|
-
app.use("/api/v1/comments/*", bearerAuth(keys, projects, ttls.absoluteS));
|
|
297
|
-
app.use("/api/v1/projects/:uid/comments/*", bearerAuth(keys, projects, ttls.absoluteS));
|
|
301
|
+
app.use("/api/v1/comments/*", bearerAuth(keys, projects, ttls.absoluteS, reviewers));
|
|
302
|
+
app.use("/api/v1/projects/:uid/comments/*", bearerAuth(keys, projects, ttls.absoluteS, reviewers));
|
|
298
303
|
app.route("/", commentEditRoutes({ sql }));
|
|
299
|
-
app.use("/api/v1/projects/:uid/attachments", bearerAuth(keys, projects, ttls.absoluteS));
|
|
304
|
+
app.use("/api/v1/projects/:uid/attachments", bearerAuth(keys, projects, ttls.absoluteS, reviewers));
|
|
300
305
|
app.route("/", attachmentRoutes({
|
|
301
306
|
sql,
|
|
302
307
|
keys,
|
package/dist/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export function createReviewerCache(sql, opts = {}) {
|
|
2
|
+
const ttl = opts.ttlMs ?? 10_000;
|
|
3
|
+
const now = opts.now ?? (() => Date.now());
|
|
4
|
+
const entries = new Map();
|
|
5
|
+
const inflight = new Map();
|
|
6
|
+
async function load(id) {
|
|
7
|
+
const [row] = await sql `
|
|
8
|
+
SELECT identity_valid_after FROM reviewers WHERE id = ${id}::uuid
|
|
9
|
+
`;
|
|
10
|
+
return row?.identity_valid_after ?? null;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
async validAfter(reviewerId) {
|
|
14
|
+
const hit = entries.get(reviewerId);
|
|
15
|
+
if (hit && now() - hit.at < ttl)
|
|
16
|
+
return hit.value;
|
|
17
|
+
const running = inflight.get(reviewerId);
|
|
18
|
+
if (running)
|
|
19
|
+
return running;
|
|
20
|
+
const p = load(reviewerId)
|
|
21
|
+
.then((value) => {
|
|
22
|
+
entries.set(reviewerId, { at: now(), value });
|
|
23
|
+
return value;
|
|
24
|
+
})
|
|
25
|
+
.finally(() => inflight.delete(reviewerId));
|
|
26
|
+
inflight.set(reviewerId, p);
|
|
27
|
+
return p;
|
|
28
|
+
},
|
|
29
|
+
invalidate(reviewerId) {
|
|
30
|
+
entries.delete(reviewerId);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=reviewerCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewerCache.js","sourceRoot":"","sources":["../src/reviewerCache.ts"],"names":[],"mappings":"AAyDA,MAAM,UAAU,mBAAmB,CACjC,GAAiB,EACjB,OAA+C,EAAE;IAEjD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC;IACjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAiB,CAAC;IACzC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAgC,CAAC;IAEzD,KAAK,UAAU,IAAI,CAAC,EAAU;QAC5B,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,GAAG,CAAyC;8DACN,EAAE;KAC3D,CAAC;QACF,OAAO,GAAG,EAAE,oBAAoB,IAAI,IAAI,CAAC;IAC3C,CAAC;IAED,OAAO;QACL,KAAK,CAAC,UAAU,CAAC,UAAU;YACzB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACpC,IAAI,GAAG,IAAI,GAAG,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG;gBAAE,OAAO,GAAG,CAAC,KAAK,CAAC;YAElD,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACzC,IAAI,OAAO;gBAAE,OAAO,OAAO,CAAC;YAE5B,MAAM,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC;iBACvB,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;gBACd,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC9C,OAAO,KAAK,CAAC;YACf,CAAC,CAAC;iBACD,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;YAC9C,QAAQ,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YAC5B,OAAO,CAAC,CAAC;QACX,CAAC;QACD,UAAU,CAAC,UAAU;YACnB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/routes/auth.js
CHANGED
|
@@ -18,7 +18,11 @@ import { verifySession } from "../session.js";
|
|
|
18
18
|
* reported: a reviewer whose link was revoked mid-session needs F-19, not a
|
|
19
19
|
* silent downgrade to read-only that looks like the widget quietly breaking.
|
|
20
20
|
*/
|
|
21
|
-
export function bearerAuth(keys, projects, absoluteTtlS
|
|
21
|
+
export function bearerAuth(keys, projects, absoluteTtlS,
|
|
22
|
+
/** Per-identity revocation (05 §4.6). Optional so existing callers and
|
|
23
|
+
* tests keep working; without it the check falls back to refresh-time
|
|
24
|
+
* only, which is the behaviour this argument exists to end. */
|
|
25
|
+
reviewers) {
|
|
22
26
|
return async (c, next) => {
|
|
23
27
|
const token = /^Bearer (.+)$/i.exec(c.req.header("Authorization") ?? "")?.[1];
|
|
24
28
|
const uid = c.req.param("uid");
|
|
@@ -33,6 +37,33 @@ export function bearerAuth(keys, projects, absoluteTtlS) {
|
|
|
33
37
|
absoluteTtlS,
|
|
34
38
|
});
|
|
35
39
|
if (v.ok) {
|
|
40
|
+
/**
|
|
41
|
+
* PER-IDENTITY REVOCATION — 05 §4.6 / §1601's "10-second cache miss
|
|
42
|
+
* path", which existed in the spec and not in the code.
|
|
43
|
+
*
|
|
44
|
+
* `session_epoch` above revokes a whole project's links and costs
|
|
45
|
+
* nothing, because the project row was already in memory. This is the
|
|
46
|
+
* other case: ONE person signed out — what a host app's logout hook
|
|
47
|
+
* calls — while the round carries on for everybody else. It was checked
|
|
48
|
+
* only when a token refreshed, so a signed-out reviewer kept working
|
|
49
|
+
* for up to the 15-minute sliding TTL.
|
|
50
|
+
*
|
|
51
|
+
* Cached ten seconds per reviewer rather than read per request, because
|
|
52
|
+
* this middleware makes no database call at all and that is worth
|
|
53
|
+
* keeping. `iat` is seconds; the column is a timestamp.
|
|
54
|
+
*/
|
|
55
|
+
if (reviewers) {
|
|
56
|
+
const validAfter = await reviewers.validAfter(v.claims.sub).catch(() => null);
|
|
57
|
+
if (validAfter && v.claims.iat * 1000 < validAfter.getTime()) {
|
|
58
|
+
return c.json({
|
|
59
|
+
error: {
|
|
60
|
+
code: "session_revoked",
|
|
61
|
+
message: "This reviewer has been signed out.",
|
|
62
|
+
requestId: c.get("requestId"),
|
|
63
|
+
},
|
|
64
|
+
}, 401);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
36
67
|
c.set("session", v.claims);
|
|
37
68
|
return next();
|
|
38
69
|
}
|
package/dist/routes/auth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/routes/auth.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAsB,MAAM,eAAe,CAAC;AAElE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,UAAU,CACxB,IAAa,EACb,QAAsB,EACtB,YAAoB;AACpB;;gEAEgE;AAChE,SAAyB;IAEzB,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9E,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,EAAE,CAAC;QAElC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,EAAE,CAAC;QAE5B,MAAM,CAAC,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE;YACzC,UAAU,EAAE,GAAG;YACf,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,YAAY;SACb,CAAC,CAAC;QAEH,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC;YACT;;;;;;;;;;;;;;eAcG;YACH,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;gBAC9E,IAAI,UAAU,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,GAAG,IAAI,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;oBAC7D,OAAO,CAAC,CAAC,IAAI,CACX;wBACE,KAAK,EAAE;4BACL,IAAI,EAAE,iBAAiB;4BACvB,OAAO,EAAE,oCAAoC;4BAC7C,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;yBAC9B;qBACF,EACD,GAAG,CACJ,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,MAAuB,CAAC,CAAC;YAC5C,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,sEAAsE;QACtE,wEAAwE;QACxE,wEAAwE;QACxE,0DAA0D;QAC1D,IAAI,CAAC,CAAC,MAAM,KAAK,iBAAiB,EAAE,CAAC;YACnC,OAAO,CAAC,CAAC,IAAI,CACX;gBACE,KAAK,EAAE;oBACL,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,qEAAqE;oBAC9E,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC;iBAC9B;aACF,EACD,GAAG,CACJ,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -150,6 +150,7 @@ export const storageKey = {
|
|
|
150
150
|
session: (uid) => `snag:session:${uid}`,
|
|
151
151
|
identity: IDENTITY_KEY,
|
|
152
152
|
threads: (uid, env) => `snag:threads:${uid}:${env}`,
|
|
153
|
+
seen: (uid, env) => `snag:seen:${uid}:${env}`,
|
|
153
154
|
counts: (origin) => `snag:counts:${origin}`,
|
|
154
155
|
draft: (route, draftId) => `snag:draft:${route}:${draftId}`,
|
|
155
156
|
outbox: (uid) => `snag:outbox:${uid}`,
|
|
@@ -169,6 +170,7 @@ export const STORAGE_KEY_PATTERNS = [
|
|
|
169
170
|
"^snag:session:.+$",
|
|
170
171
|
"^snag:identity$",
|
|
171
172
|
"^snag:threads:.+:.+$",
|
|
173
|
+
"^snag:seen:.+:.+$",
|
|
172
174
|
"^snag:counts:.+$",
|
|
173
175
|
"^snag:draft:.+:.+$",
|
|
174
176
|
"^snag:outbox:.+$",
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@snagset/server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
-
"description": "The Snagset server
|
|
6
|
+
"description": "The Snagset server: API, dashboard and widget in one package. Node and Postgres, or Vercel.",
|
|
7
7
|
"license": "AGPL-3.0-only",
|
|
8
8
|
"bin": {
|
|
9
9
|
"snagset": "./dist/bin.js"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:root{color-scheme:light dark;--ink: #181716;--ink-soft: #585755;--ink-faint: #6b6a68;--bg: #faf8f6;--surface: #fefdfc;--line: #e4e3e0;--line-soft: #eeecea;--line-strong: #939290;--accent: #2a51b8;--on-accent: #ffffff;--accent-soft: #e9f0ff;--warn: #9a2929;--open: #006f96;--progress: #9c542b;--review: #725ba1;--resolved: #417332;--mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;--sans: system-ui, -apple-system, "Segoe UI", Inter, sans-serif;--radius: 6px}@media(prefers-color-scheme:dark){:root{--ink: #f0eeec;--ink-soft: #a7a6a4;--ink-faint: #8e8c8b;--bg: #100f0e;--surface: #1d1c1a;--line: #2e2c2b;--line-soft: #242321;--line-strong: #696866;--accent: #8aafff;--on-accent: #100f0e;--accent-soft: #17223b;--warn: #ed8c84;--open: #3b9dc8;--progress: #cd8058;--review: #9e87d1;--resolved: #6ca05d}}*{box-sizing:border-box}body{margin:0;font:14px/1.5 var(--sans);color:var(--ink);background:var(--bg);-webkit-font-smoothing:antialiased}button{font:inherit;color:inherit}.shell{display:flex;flex-direction:column;height:100vh;overflow:hidden}.topbar{display:flex;align-items:center;gap:16px;padding:0 16px;height:52px;flex:none;border-bottom:1px solid var(--line);background:var(--surface)}.brand{font-weight:620;letter-spacing:-.01em;margin-inline-end:4px}.brand span{color:var(--ink-faint);font-weight:400}.topbar select{font:inherit;padding:4px 8px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--surface);color:inherit}.spacer{flex:1}.who{color:var(--ink-soft);font-size:13px}.linkish{background:none;border:0;padding:4px 6px;color:var(--ink-soft);cursor:pointer;border-radius:var(--radius)}.linkish:hover{background:var(--line-soft);color:var(--ink)}.inbox{flex:1;display:grid;grid-template-columns:minmax(300px,380px) 1fr;min-height:0;overflow:hidden}@media(max-width:900px){.inbox{grid-template-columns:1fr}.inbox>.detail:not(.detail-open){display:none}}.list{border-inline-end:1px solid var(--line);background:var(--surface);display:flex;flex-direction:column;min-height:0}.filters{display:flex;gap:6px;padding:10px 12px;border-bottom:1px solid var(--line-soft);flex-wrap:wrap;align-items:center}.filters input[type=search]{font:inherit;flex:1;min-width:120px;padding:5px 9px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--bg);color:inherit}.chip{font:500 12px/1 var(--sans);padding:5px 9px;border:1px solid var(--line-strong);border-radius:999px;background:transparent;color:var(--ink-soft);cursor:pointer}.chip[aria-pressed=true]{background:var(--accent-soft);border-color:transparent;color:var(--ink);font-weight:600}.rows{overflow-y:auto;flex:1}.row{display:block;width:100%;text-align:start;border:0;border-bottom:1px solid var(--line-soft);background:none;padding:11px 12px;cursor:pointer}.row:hover{background:var(--line-soft)}.row[aria-current=true]{background:var(--accent-soft);border-inline-start:3px solid var(--accent);padding-inline-start:9px}.row:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.row-top{display:flex;align-items:center;gap:8px}.key{font:600 12px/1 var(--mono);color:var(--ink-faint)}.row-body{margin:4px 0 0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.row-meta{margin-top:5px;font-size:12px;color:var(--ink-faint);display:flex;gap:8px}.status{font:600 11px/1 var(--sans);text-transform:uppercase;letter-spacing:.04em;padding:3px 7px;border-radius:999px;border:1px solid currentColor}.status-open{color:var(--open)}.status-progress{color:var(--progress)}.status-review{color:var(--review)}.status-resolved{color:var(--resolved)}.detail{overflow-y:auto;min-height:0;padding:22px 26px 60px}.detail-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}.detail-head h1{font:600 19px/1.3 var(--sans);margin:0;letter-spacing:-.01em}.shot{margin:18px 0;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;background:var(--surface)}.shot img{display:block;width:100%;height:auto}.shot figcaption{font:12px/1.4 var(--mono);color:var(--ink-faint);padding:7px 10px;border-top:1px solid var(--line-soft)}.no-shot{margin:18px 0;padding:22px;border:1px dashed var(--line);border-radius:var(--radius);color:var(--ink-soft);background:var(--surface)}.thread{margin:22px 0;display:flex;flex-direction:column;gap:14px}.comment{border-inline-start:2px solid var(--line);padding-inline-start:12px}.comment-head{display:flex;gap:8px;align-items:baseline;font-size:13px}.comment-head b{font-weight:600}.comment p{margin:3px 0 0;white-space:pre-wrap}.agent{font:600 10px/1 var(--sans);text-transform:uppercase;letter-spacing:.05em;padding:2px 5px;border-radius:3px;background:var(--review);color:var(--surface)}.block{margin:22px 0 0;border-top:1px solid var(--line);padding-top:14px}.block h2{font:600 11px/1 var(--sans);text-transform:uppercase;letter-spacing:.06em;color:var(--ink-faint);margin:0 0 10px}.kv{display:grid;grid-template-columns:max-content 1fr;gap:4px 14px;font-size:13px}.kv dt{color:var(--ink-soft)}.kv dd{margin:0;font-family:var(--mono);font-size:12.5px;overflow-wrap:anywhere}.warn{color:var(--warn)}.actions{display:flex;gap:8px;margin:18px 0 0;flex-wrap:wrap}.btn{font:500 13px/1 var(--sans);padding:8px 12px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--surface);cursor:pointer}.btn:hover{border-color:var(--ink-faint)}.btn-primary{background:var(--accent);border-color:transparent;color:var(--on-accent)}.btn-primary:hover{filter:brightness(1.08)}.empty{padding:48px 26px;color:var(--ink-soft);max-width:46ch}.empty h2{font:600 16px/1.4 var(--sans);color:var(--ink);margin:0 0 6px}.gate{min-height:100vh;display:grid;place-items:center;padding:24px}.card{width:100%;max-width:360px;background:var(--surface);border:1px solid var(--line);border-radius:10px;padding:26px}.card h1{font:600 18px/1.3 var(--sans);margin:0 0 4px}.card p.sub{margin:0 0 18px;color:var(--ink-soft);font-size:13px}.field{display:block;margin-bottom:12px}.field span{display:block;font-size:12.5px;color:var(--ink-soft);margin-bottom:4px}.field input,.field textarea{font:inherit;width:100%;padding:8px 10px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--bg);color:inherit}.field textarea{resize:vertical;min-height:60px}.field input:focus-visible,.field textarea:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.composer{margin:18px 0 0;max-width:480px}.composer .field{margin-bottom:8px}.composer .btn-primary{padding:8px 14px}.card .btn-primary{width:100%;padding:10px}.err{margin:0 0 14px;padding:9px 11px;border-radius:var(--radius);background:color-mix(in srgb,var(--warn) 12%,transparent);color:var(--warn);font-size:13px}.foot{flex:none;border-top:1px solid var(--line);padding:10px 16px;font:12px/1.4 var(--mono);color:var(--ink-faint);display:flex;gap:12px;flex-wrap:wrap}.carryover{display:block;width:100%;text-align:start;flex:none;border:0;border-bottom:1px solid color-mix(in srgb,var(--warn) 35%,transparent);background:color-mix(in srgb,var(--warn) 12%,transparent);color:var(--warn);font:inherit;padding:9px 16px;cursor:pointer}.carryover:hover{background:color-mix(in srgb,var(--warn) 20%,transparent)}.links{flex:1;display:grid;grid-template-columns:1fr minmax(300px,380px);gap:0;min-height:0;overflow:hidden}@media(max-width:900px){.links{grid-template-columns:1fr;overflow-y:auto}}.links-list{padding:22px 26px;overflow-y:auto;min-height:0}.links-title{font:600 19px/1.3 var(--sans);margin:0 0 16px;letter-spacing:-.01em}.links-side{border-inline-start:1px solid var(--line);background:var(--surface);padding:22px;overflow-y:auto;min-height:0;display:flex;flex-direction:column;gap:16px}.links-side .card{max-width:none;padding:20px}.links-side .card h2{font:600 15px/1.3 var(--sans);margin:0 0 4px}.links-side .card p.sub{margin:0 0 14px;color:var(--ink-soft);font-size:13px}.link-table{width:100%;border-collapse:collapse;font-size:13px}.link-table th{text-align:start;font:600 11px/1 var(--sans);text-transform:uppercase;letter-spacing:.05em;color:var(--ink-faint);padding:0 10px 8px 0;border-bottom:1px solid var(--line)}.link-table td{padding:10px 10px 10px 0;border-bottom:1px solid var(--line-soft);vertical-align:top}.link-table tr.link-dead{color:var(--ink-faint)}.link-round{display:inline-block;margin-inline-start:6px;font-size:11px;color:var(--ink-faint);border:1px solid var(--line);border-radius:999px;padding:1px 7px}.minted{border-color:var(--accent)}.token-box{display:flex;align-items:center;gap:8px;padding:9px 11px;border:1px solid var(--line);border-radius:var(--radius);background:var(--bg)}.token-box code{flex:1;font:12.5px/1.4 var(--mono);overflow-wrap:anywhere}.field select{font:inherit;width:100%;padding:8px 10px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--bg);color:inherit}.sites{max-width:720px;margin:0 auto;padding:24px 20px 64px;display:flex;flex-direction:column;gap:28px}.sites h2{font-size:15px;margin:0 0 12px}.sites h3{font-size:13px;margin:20px 0 8px;color:var(--ink-soft)}.sites form{display:flex;flex-direction:column;gap:14px}.sites label{display:flex;flex-direction:column;gap:5px;font-size:13px;color:var(--ink-soft)}.sites input{font:inherit;padding:8px 10px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--bg);color:inherit}.sites input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.sites small{color:var(--ink-faint);font-size:12px;line-height:1.5}.sites small code{font:11.5px/1 var(--mono)}.sites button[type=submit]{align-self:flex-start;font:inherit;padding:8px 14px;border:1px solid var(--accent);border-radius:var(--radius);background:var(--accent);color:var(--on-accent);cursor:pointer}.sites button[type=submit]:disabled{opacity:.45;cursor:default}.sites .error{color:var(--warn);font-size:13px;margin:0}.site-add,.site-made,.site-list{border:1px solid var(--line);border-radius:var(--radius);background:var(--surface);padding:18px 20px}.site-made{border-color:var(--accent)}.site-made p{font-size:13px;color:var(--ink-soft);margin:0 0 10px}.site-made pre{margin:0 0 8px;padding:11px 12px;border:1px solid var(--line);border-radius:var(--radius);background:var(--bg);overflow-x:auto}.site-made pre code{font:12.5px/1.5 var(--mono);white-space:pre}.site-made form{flex-direction:row;align-items:center;gap:8px;margin-top:10px}.site-made form input{flex:1}.site-made form button{font:inherit;padding:8px 12px;border:1px solid var(--line);border-radius:var(--radius);background:var(--bg);color:inherit;cursor:pointer}.origins{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px}.origins li code{font:11.5px/1 var(--mono);padding:4px 8px;border:1px solid var(--line);border-radius:999px;background:var(--bg)}.site-list ul{list-style:none;margin:0;padding:0}.site-list li{display:flex;align-items:baseline;gap:10px;padding:9px 0;border-bottom:1px solid var(--line-soft);font-size:13px}.site-list li:last-child{border-bottom:0}.site-list li code{font:11.5px/1 var(--mono);color:var(--ink-faint)}.site-list li span{margin-left:auto;color:var(--ink-faint);font-size:12px}.setup{max-width:460px;margin:0 auto;padding:56px 24px 64px}.setup h1{font-size:20px;margin:0 0 8px}.setup-lede{color:var(--ink-soft);font-size:13px;line-height:1.6;margin:0 0 24px}.setup form{display:flex;flex-direction:column;gap:16px}.setup label{display:flex;flex-direction:column;gap:5px;font-size:13px;color:var(--ink-soft)}.setup-opt{color:var(--ink-faint);font-weight:400}.setup input{font:inherit;padding:9px 11px;border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--bg);color:inherit}.setup input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}.setup small{color:var(--ink-faint);font-size:12px;line-height:1.5}.setup button[type=submit],.setup-actions button:not(.linkish){font:inherit;padding:9px 14px;border:1px solid var(--accent);border-radius:var(--radius);background:var(--accent);color:var(--on-accent);cursor:pointer}.setup button[type=submit]:disabled{opacity:.45;cursor:default}.setup .error{color:var(--warn);font-size:13px;margin:0}.setup pre{margin:0 0 12px;padding:11px 12px;border:1px solid var(--line);border-radius:var(--radius);background:var(--bg);overflow-x:auto}.setup pre code{font:12.5px/1.5 var(--mono);white-space:pre}.setup-actions{display:flex;align-items:center;gap:12px}.setup-note{color:var(--ink-faint);font-size:12.5px;line-height:1.6;margin:24px 0 0}.site-audience{display:flex;flex-direction:column;gap:8px;margin:0 0 12px}.site-audience label{display:flex;gap:9px;align-items:baseline;font-size:12.5px;color:var(--ink-soft);line-height:1.5;cursor:pointer}.site-audience input{accent-color:var(--accent)}.site-audience strong{color:var(--ink);font-weight:600}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){const n=document.createElement("link").relList;if(n&&n.supports&&n.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))o(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const a of s.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&o(a)}).observe(document,{childList:!0,subtree:!0});function r(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function o(i){if(i.ep)return;i.ep=!0;const s=r(i);fetch(i.href,s)}})();var ee,C,Pe,U,pe,xe,Ie,te,V,F,Ee,ae,ie,se,Q={},X=[],Be=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,ne=Array.isArray;function D(e,n){for(var r in n)e[r]=n[r];return e}function ce(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function We(e,n,r){var o,i,s,a={};for(s in n)s=="key"?o=n[s]:s=="ref"?i=n[s]:a[s]=n[s];if(arguments.length>2&&(a.children=arguments.length>3?ee.call(arguments,2):r),typeof e=="function"&&e.defaultProps!=null)for(s in e.defaultProps)a[s]===void 0&&(a[s]=e.defaultProps[s]);return K(e,a,o,i,null)}function K(e,n,r,o,i){var s={type:e,props:n,key:r,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:i??++Pe,__i:-1,__u:0};return i==null&&C.vnode!=null&&C.vnode(s),s}function N(e){return e.children}function J(e,n){this.props=e,this.context=n}function q(e,n){if(n==null)return e.__?q(e.__,e.__i+1):null;for(var r;n<e.__k.length;n++)if((r=e.__k[n])!=null&&r.__e!=null)return r.__e;return typeof e.type=="function"?q(e):null}function Ge(e){if(e.__P&&e.__d){var n=e.__v,r=n.__e,o=[],i=[],s=D({},n);s.__v=n.__v+1,C.vnode&&C.vnode(s),de(e.__P,s,n,e.__n,e.__P.namespaceURI,32&n.__u?[r]:null,o,r??q(n),!!(32&n.__u),i),s.__v=n.__v,s.__.__k[s.__i]=s,Le(o,s,i),n.__e=n.__=null,s.__e!=r&&je(s)}}function je(e){if((e=e.__)!=null&&e.__c!=null)return e.__e=e.__c.base=null,e.__k.some(function(n){if(n!=null&&n.__e!=null)return e.__e=e.__c.base=n.__e}),je(e)}function me(e){(!e.__d&&(e.__d=!0)&&U.push(e)&&!Z.__r++||pe!=C.debounceRendering)&&((pe=C.debounceRendering)||xe)(Z)}function Z(){try{for(var e,n=1;U.length;)U.length>n&&U.sort(Ie),e=U.shift(),n=U.length,Ge(e)}finally{U.length=Z.__r=0}}function Ne(e,n,r,o,i,s,a,c,_,d,p){var k,l,h,m,y,b,f=o&&o.__k||X,g=n.length;for(_=ze(r,n,f,_,g),k=0;k<g;k++)(h=r.__k[k])!=null&&(l=h.__i!=-1&&f[h.__i]||Q,h.__i=k,b=de(e,h,l,i,s,a,c,_,d,p),m=h.__e,h.ref&&l.ref!=h.ref&&(l.ref&&ue(l.ref,null,h),p.push(h.ref,h.__c||m,h)),y==null&&m!=null&&(y=m),4&h.__u?(_=Re(h,_,e),l.__e&&(l.__e=null)):typeof h.type=="function"&&b!==void 0?_=b:m&&(_=m.nextSibling),h.__u&=-7);return r.__e=y,_}function ze(e,n,r,o,i){var s,a,c,_,d,p=r.length,k=p,l=0;for(e.__k=new Array(i),s=0;s<i;s++)(a=n[s])!=null&&typeof a!="boolean"&&typeof a!="function"?(typeof a=="string"||typeof a=="number"||typeof a=="bigint"||a.constructor==String?a=e.__k[s]=K(null,a,null,null,null):ne(a)?a=e.__k[s]=K(N,{children:a},null,null,null):a.constructor===void 0&&a.__b>0?a=e.__k[s]=K(a.type,a.props,a.key,a.ref?a.ref:null,a.__v):e.__k[s]=a,_=s+l,a.__=e,a.__b=e.__b+1,c=null,(d=a.__i=Ve(a,r,_,k))!=-1&&(k--,(c=r[d])&&(c.__u|=2)),c==null||c.__v==null?(d==-1&&(i>p?l--:i<p&&l++),typeof a.type!="function"&&(a.__u|=4)):d!=_&&(d==_-1?l--:d==_+1?l++:(d>_?l--:l++,a.__u|=4))):e.__k[s]=null;if(k)for(s=0;s<p;s++)(c=r[s])!=null&&(2&c.__u)==0&&(c.__e==o&&(o=q(c)),qe(c,c));return o}function Re(e,n,r){var o,i;if(typeof e.type=="function"){for(o=e.__k,i=0;o&&i<o.length;i++)o[i]&&(o[i].__=e,n=Re(o[i],n,r));return n}e.__e!=n&&(n&&e.type&&!n.parentNode&&(n=q(e)),n=r.insertBefore(e.__e,n||null));do n=n&&n.nextSibling;while(n!=null&&n.nodeType==8);return n}function Ve(e,n,r,o){var i,s,a,c=e.key,_=e.type,d=n[r],p=d!=null&&(2&d.__u)==0;if(d===null&&c==null||p&&c==d.key&&_==d.type)return r;if(o>(p?1:0)){for(i=r-1,s=r+1;i>=0||s<n.length;)if((d=n[a=i>=0?i--:s++])!=null&&(2&d.__u)==0&&c==d.key&&_==d.type)return a}return-1}function fe(e,n,r){n[0]=="-"?e.setProperty(n,r??""):e[n]=r==null?"":typeof r!="number"||Be.test(n)?r:r+"px"}function G(e,n,r,o,i){var s,a;e:if(n=="style")if(typeof r=="string")e.style.cssText=r;else{if(typeof o=="string"&&(e.style.cssText=o=""),o)for(n in o)r&&n in r||fe(e.style,n,"");if(r)for(n in r)o&&r[n]==o[n]||fe(e.style,n,r[n])}else if(n[0]=="o"&&n[1]=="n")s=n!=(n=n.replace(Ee,"$1")),a=n.toLowerCase(),n=a in e||n=="onFocusOut"||n=="onFocusIn"?a.slice(2):n.slice(2),e.l||(e.l={}),e.l[n+s]=r,r?o?r[F]=o[F]:(r[F]=ae,e.addEventListener(n,s?se:ie,s)):e.removeEventListener(n,s?se:ie,s);else{if(i=="http://www.w3.org/2000/svg")n=n.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(n!="width"&&n!="height"&&n!="href"&&n!="list"&&n!="form"&&n!="tabIndex"&&n!="download"&&n!="rowSpan"&&n!="colSpan"&&n!="role"&&n!="popover"&&n in e)try{e[n]=r??"";break e}catch{}typeof r=="function"||(r==null||r===!1&&n[4]!="-"?e.removeAttribute(n):e.setAttribute(n,n=="popover"&&r==1?"":r))}}function ve(e){return function(n){if(this.l){var r=this.l[n.type+e];if(n[V]==null)n[V]=ae++;else if(n[V]<r[F])return;return r(C.event?C.event(n):n)}}}function de(e,n,r,o,i,s,a,c,_,d){var p,k,l,h,m,y,b,f,g,T,R,v,u,S,A,$,j=n.type;if(n.constructor!==void 0)return null;128&r.__u&&(_=!!(32&r.__u),s=[c=n.__e=r.__e]),(p=C.__b)&&p(n);e:if(typeof j=="function"){k=a.length;try{if(g=n.props,T=j.prototype&&j.prototype.render,R=(p=j.contextType)&&o[p.__c],v=p?R?R.props.value:p.__:o,r.__c?f=(l=n.__c=r.__c).__=l.__E:(T?n.__c=l=new j(g,v):(n.__c=l=new J(g,v),l.constructor=j,l.render=Je),R&&R.sub(l),l.state||(l.state={}),l.__n=o,h=l.__d=!0,l.__h=[],l._sb=[]),T&&l.__s==null&&(l.__s=l.state),T&&j.getDerivedStateFromProps!=null&&(l.__s==l.state&&(l.__s=D({},l.__s)),D(l.__s,j.getDerivedStateFromProps(g,l.__s))),m=l.props,y=l.state,l.__v=n,h)T&&j.getDerivedStateFromProps==null&&l.componentWillMount!=null&&l.componentWillMount(),T&&l.componentDidMount!=null&&l.__h.push(l.componentDidMount);else{if(T&&j.getDerivedStateFromProps==null&&g!==m&&l.componentWillReceiveProps!=null&&l.componentWillReceiveProps(g,v),n.__v==r.__v||!l.__e&&l.shouldComponentUpdate!=null&&l.shouldComponentUpdate(g,l.__s,v)===!1){n.__v!=r.__v&&(l.props=g,l.state=l.__s,l.__d=!1),n.__e=r.__e,n.__k=r.__k,n.__k.some(function(O){O&&(O.__=n)}),X.push.apply(l.__h,l._sb),l._sb=[],l.__h.length&&a.push(l),c=q(r);break e}l.componentWillUpdate!=null&&l.componentWillUpdate(g,l.__s,v),T&&l.componentDidUpdate!=null&&l.__h.push(function(){l.componentDidUpdate(m,y,b)})}if(l.context=v,l.props=g,l.__P=e,l.__e=!1,u=C.__r,S=0,T)l.state=l.__s,l.__d=!1,u&&u(n),p=l.render(l.props,l.state,l.context),X.push.apply(l.__h,l._sb),l._sb=[];else do l.__d=!1,u&&u(n),p=l.render(l.props,l.state,l.context),l.state=l.__s;while(l.__d&&++S<25);l.state=l.__s,l.getChildContext!=null&&(o=D(D({},o),l.getChildContext())),T&&!h&&l.getSnapshotBeforeUpdate!=null&&(b=l.getSnapshotBeforeUpdate(m,y)),A=p!=null&&p.type===N&&p.key==null?Ue(p.props.children):p,c=Ne(e,ne(A)?A:[A],n,r,o,i,s,a,c,_,d),l.base=n.__e,n.__u&=-161,l.__h.length&&a.push(l),f&&(l.__E=l.__=null)}catch(O){if(a.length=k,n.__v=null,_||s!=null){if(O.then){for(n.__u|=_?160:128;c&&c.nodeType==8&&c.nextSibling;)c=c.nextSibling;s!=null&&(s[s.indexOf(c)]=null),n.__e=c}else if(s!=null)for($=s.length;$--;)ce(s[$])}else n.__e=r.__e;n.__k==null&&(n.__k=r.__k||[]),O.then||De(n),C.__e(O,n,r)}}else s==null&&n.__v==r.__v?(n.__k=r.__k,n.__e=r.__e):c=n.__e=Ke(r.__e,n,r,o,i,s,a,_,d);return(p=C.diffed)&&p(n),128&n.__u?void 0:c}function De(e){e&&(e.__c&&(e.__c.__e=!0),e.__k&&e.__k.some(De))}function Le(e,n,r){for(var o=0;o<r.length;o++)ue(r[o],r[++o],r[++o]);C.__c&&C.__c(n,e),e.some(function(i){try{e=i.__h,i.__h=[],e.some(function(s){s.call(i)})}catch(s){C.__e(s,i.__v)}})}function Ue(e){return typeof e!="object"||e==null||e.__b>0?e:ne(e)?e.map(Ue):e.constructor!==void 0?null:D({},e)}function Ke(e,n,r,o,i,s,a,c,_){var d,p,k,l,h,m,y,b=r.props||Q,f=n.props,g=n.type;if(g=="svg"?i="http://www.w3.org/2000/svg":g=="math"?i="http://www.w3.org/1998/Math/MathML":i||(i="http://www.w3.org/1999/xhtml"),s!=null){for(d=0;d<s.length;d++)if((h=s[d])&&"setAttribute"in h==!!g&&(g?h.localName==g:h.nodeType==3)){e=h,s[d]=null;break}}if(e==null){if(g==null)return document.createTextNode(f);e=document.createElementNS(i,g,f.is&&f),c&&(C.__m&&C.__m(n,s),c=!1),s=null}if(g==null)b===f||c&&e.data==f||(e.data=f);else{if(s=g=="textarea"&&f.defaultValue!=null?null:s&&ee.call(e.childNodes),!c&&s!=null)for(b={},d=0;d<e.attributes.length;d++)b[(h=e.attributes[d]).name]=h.value;for(d in b)h=b[d],d=="dangerouslySetInnerHTML"?k=h:d=="children"||d in f||d=="value"&&"defaultValue"in f||d=="checked"&&"defaultChecked"in f||G(e,d,null,h,i);for(d in f)h=f[d],d=="children"?l=h:d=="dangerouslySetInnerHTML"?p=h:d=="value"?m=h:d=="checked"?y=h:c&&typeof h!="function"||b[d]===h||G(e,d,h,b[d],i);if(p)c||k&&(p.__html==k.__html||p.__html==e.innerHTML)||(e.innerHTML=p.__html),n.__k=[];else if(k&&(e.innerHTML=""),Ne(n.type=="template"?e.content:e,ne(l)?l:[l],n,r,o,g=="foreignObject"?"http://www.w3.org/1999/xhtml":i,s,a,s?s[0]:r.__k&&q(r,0),c,_),s!=null)for(d=s.length;d--;)ce(s[d]);c&&g!="textarea"||(d="value",g=="progress"&&m==null?e.removeAttribute("value"):m!=null&&(m!==e[d]||g=="progress"&&!m||g=="option"&&m!=b[d])&&G(e,d,m,b[d],i),d="checked",y!=null&&y!=e[d]&&G(e,d,y,b[d],i))}return e}function ue(e,n,r){try{if(typeof e=="function"){var o=typeof e.__u=="function";o&&e.__u(),o&&n==null||(e.__u=e(n))}else e.current=n}catch(i){C.__e(i,r)}}function qe(e,n,r){var o,i;if(C.unmount&&C.unmount(e),(o=e.ref)&&(o.current&&o.current!=e.__e||ue(o,null,n)),(o=e.__c)!=null){if(o.componentWillUnmount)try{o.componentWillUnmount()}catch(s){C.__e(s,n)}o.base=o.__P=o.__n=null}if(o=e.__k)for(i=0;i<o.length;i++)o[i]&&qe(o[i],n,r||typeof e.type!="function");r||ce(e.__e),e.__c=e.__=e.__e=void 0}function Je(e,n,r){return this.constructor(e,r)}function Ye(e,n,r){var o,i,s,a;n==document&&(n=document.documentElement),C.__&&C.__(e,n),i=(o=!1)?null:n.__k,s=[],a=[],de(n,e=n.__k=We(N,null,[e]),i||Q,Q,n.namespaceURI,i?null:n.firstChild?ee.call(n.childNodes):null,s,i?i.__e:n.firstChild,o,a),Le(s,e,a),e.props.children=null}ee=X.slice,C={__e:function(e,n,r,o){for(var i,s,a;n=n.__;)if((i=n.__c)&&!i.__)try{if((s=i.constructor)&&s.getDerivedStateFromError!=null&&(i.setState(s.getDerivedStateFromError(e)),a=i.__d),i.componentDidCatch!=null&&(i.componentDidCatch(e,o||{}),a=i.__d),a)return i.__E=i}catch(c){e=c}throw e}},Pe=0,J.prototype.setState=function(e,n){var r;r=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=D({},this.state),typeof e=="function"&&(e=e(D({},r),this.props)),e&&D(r,e),e!=null&&this.__v&&(n&&this._sb.push(n),me(this))},J.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),me(this))},J.prototype.render=N,U=[],xe=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,Ie=function(e,n){return e.__v.__b-n.__v.__b},Z.__r=0,te=Math.random().toString(8),V="__d"+te,F="__a"+te,Ee=/(PointerCapture)$|Capture$/i,ae=0,ie=ve(!1),se=ve(!0);var Qe=0;function t(e,n,r,o,i,s){n||(n={});var a,c,_=n;if("ref"in _)for(c in _={},n)c=="ref"?a=n[c]:_[c]=n[c];var d={type:e,props:_,key:r,ref:a,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Qe,__i:-1,__u:0,__source:i,__self:s};if(typeof e=="function"&&(a=e.defaultProps))for(c in a)_[c]===void 0&&(_[c]=a[c]);return C.vnode&&C.vnode(d),d}var B,P,re,ge,W=0,Oe=[],x=C,ye=x.__b,be=x.__r,we=x.diffed,ke=x.__c,Se=x.unmount,Ce=x.__;function _e(e,n){x.__h&&x.__h(P,e,W||n),W=0;var r=P.__H||(P.__H={__:[],__h:[]});return e>=r.__.length&&r.__.push({}),r.__[e]}function w(e){return W=1,Xe(Fe,e)}function Xe(e,n,r){var o=_e(B++,2);if(o.t=e,!o.__c&&(o.__=[Fe(void 0,n),function(c){var _=o.__N?o.__N[0]:o.__[0],d=o.t(_,c);_!==d&&(o.__N=[d,o.__[1]],o.__c.setState({}))}],o.__c=P,!P.__f)){var i=function(c,_,d){if(!o.__c.__H)return!0;var p=!1,k=o.__c.props!==c;if(o.__c.__H.__.some(function(h){if(h.__N){p=!0;var m=h.__[0];h.__=h.__N,h.__N=void 0,m!==h.__[0]&&(k=!0)}}),s){var l=s.call(this,c,_,d);return p?l||k:l}return!p||k};P.__f=!0;var s=P.shouldComponentUpdate,a=P.componentWillUpdate;P.componentWillUpdate=function(c,_,d){if(this.__e){var p=s;s=void 0,i(c,_,d),s=p}a&&a.call(this,c,_,d)},P.shouldComponentUpdate=i}return o.__N||o.__}function M(e,n){var r=_e(B++,3);!x.__s&&Me(r.__H,n)&&(r.__=e,r.u=n,P.__H.__h.push(r))}function Ze(e){return W=5,he(function(){return{current:e}},[])}function he(e,n){var r=_e(B++,7);return Me(r.__H,n)&&(r.__=e(),r.__H=n,r.__h=e),r.__}function He(e,n){return W=8,he(function(){return e},n)}function en(){for(var e;e=Oe.shift();){var n=e.__H;if(e.__P&&n)try{n.__h.some(Y),n.__h.some(oe),n.__h=[]}catch(r){n.__h=[],x.__e(r,e.__v)}}}x.__b=function(e){P=null,ye&&ye(e)},x.__=function(e,n){e&&n.__k&&n.__k.__m&&(e.__m=n.__k.__m),Ce&&Ce(e,n)},x.__r=function(e){be&&be(e),B=0;var n=(P=e.__c).__H;n&&(re===P?(n.__h=[],P.__h=[],n.__.some(function(r){r.__N&&(r.__=r.__N),r.u=r.__N=void 0})):(n.__h.some(Y),n.__h.some(oe),n.__h=[],B=0)),re=P},x.diffed=function(e){we&&we(e);var n=e.__c;n&&n.__H&&(n.__H.__h.length&&(Oe.push(n)!==1&&ge===x.requestAnimationFrame||((ge=x.requestAnimationFrame)||nn)(en)),n.__H.__.some(function(r){r.u&&(r.__H=r.u,r.u=void 0)})),re=P=null},x.__c=function(e,n){n.some(function(r){try{r.__h.some(Y),r.__h=r.__h.filter(function(o){return!o.__||oe(o)})}catch(o){n.some(function(i){i.__h&&(i.__h=[])}),n=[],x.__e(o,r.__v)}}),ke&&ke(e,n)},x.unmount=function(e){Se&&Se(e);var n,r=e.__c;r&&r.__H&&(r.__H.__.some(function(o){try{Y(o)}catch(i){n=i}}),r.__H=void 0,n&&x.__e(n,r.__v))};var $e=typeof requestAnimationFrame=="function";function nn(e){var n,r=function(){clearTimeout(o),$e&&cancelAnimationFrame(n),setTimeout(e)},o=setTimeout(r,35);$e&&(n=requestAnimationFrame(r))}function Y(e){var n=P,r=e.__c;typeof r=="function"&&(e.__c=void 0,r()),P=n}function oe(e){var n=P;e.__c=e.__(),P=n}function Me(e,n){return!e||e.length!==n.length||n.some(function(r,o){return r!==e[o]})}function Fe(e,n){return typeof n=="function"?n(e):n}const tn={csrf:"snag_csrf"},rn=tn.csrf,sn={csrf:"x-snagset-csrf"};class L extends Error{status;code;constructor(n,r){super(r.message),this.status=n,this.code=r.code}}function on(){for(const e of document.cookie.split(";")){const n=e.indexOf("=");if(n>0&&e.slice(0,n).trim()===rn)return e.slice(n+1).trim()}return""}async function E(e,n,r){const o=await fetch(n,{method:e,credentials:"same-origin",headers:{...r===void 0?{}:{"content-type":"application/json"},...e==="GET"?{}:{[sn.csrf]:on()}},...r===void 0?{}:{body:JSON.stringify(r)}});if(o.status===204)return;const i=await o.json().catch(()=>null);if(!o.ok){const s=i?.error;throw new L(o.status,s??{code:"unknown",message:`Request failed (${o.status}).`})}return i}const I={me:()=>E("GET","/api/v1/me"),setup:e=>E("POST","/api/v1/setup",e),login:(e,n)=>E("POST","/auth/login",{email:e,password:n}),logout:()=>E("POST","/auth/logout"),threads:(e,n={})=>{const r=new URLSearchParams;n.status&&r.set("status",n.status),n.route&&r.set("route",n.route),n.round&&r.set("round",String(n.round)),n.q&&r.set("q",n.q),n.since&&r.set("since",n.since);const o=r.toString();return E("GET",`/api/v1/projects/${encodeURIComponent(e)}/threads${o?`?${o}`:""}`)},createProject:(e,n)=>E("POST","/api/v1/projects",{name:e,origins:n}),setAudience:(e,n)=>E("PATCH",`/api/v1/projects/${encodeURIComponent(e)}`,{writeMode:n}),origins:e=>E("GET",`/api/v1/projects/${encodeURIComponent(e)}/origins`),addOrigin:(e,n)=>E("POST",`/api/v1/projects/${encodeURIComponent(e)}/origins`,{origin:n}),rounds:e=>E("GET",`/api/v1/projects/${encodeURIComponent(e)}/rounds`),createRound:(e,n)=>E("POST",`/api/v1/projects/${encodeURIComponent(e)}/rounds`,{name:n}),setStatus:(e,n,r)=>E("PATCH",`/api/v1/projects/${encodeURIComponent(e)}/threads/${encodeURIComponent(n)}`,{status:r}),addComment:(e,n)=>E("POST",`/api/v1/threads/${encodeURIComponent(e)}/comments`,{id:crypto.randomUUID(),body:n}),listLinks:e=>E("GET",`/api/v1/projects/${encodeURIComponent(e)}/review-links`),mintLink:(e,n)=>E("POST",`/api/v1/projects/${encodeURIComponent(e)}/review-links`,n),revokeLink:e=>E("DELETE",`/api/v1/review-links/${encodeURIComponent(e)}`)};function Te(e){const n=new Date(e),r=Math.round((Date.now()-n.getTime())/6e4);return r<1?"just now":r<60?`${r}m ago`:r<1440?`${Math.round(r/60)}h ago`:n.toLocaleDateString(void 0,{day:"numeric",month:"short"})}function ln({context:e}){const n=e?.capture,r=e?.viewport,i=[["Viewport",r?.w?`${r.w} × ${r.h}`:null],["Browser",e?.browser??e?.ua??null],["Platform",e?.os??e?.platform??null],["Device pixel ratio",e?.dpr??null]].filter(([,c])=>c!=null&&c!==""),s=n?.category&&n.category!=="ok"&&n.category!=="full";return!i.length&&!n?null:t("section",{class:"block",children:[t("h2",{children:["Capture",t("button",{type:"button",class:"linkish",style:"float:right;font-size:12px",onClick:()=>{navigator.clipboard?.writeText(JSON.stringify(e,null,2))},children:"Copy environment"})]}),i.length>0&&t("dl",{class:"kv",children:i.map(([c,_])=>t(N,{children:[t("dt",{children:c}),t("dd",{children:String(_)})]}))}),s&&t("p",{class:"warn",style:"margin:10px 0 0",children:[t("b",{children:n.category}),n.reasons?.length?` — ${n.reasons.join("; ")}`:""]}),n?.blindSpots?.length?t("p",{class:"warn",style:"margin:6px 0 0",children:[n.blindSpots.length," blind spot",n.blindSpots.length===1?"":"s",": ",n.blindSpots.join("; ")]}):null,n?.droppedCategories?.length?t("p",{class:"warn",style:"margin:6px 0 0",children:["Dropped: ",n.droppedCategories.join(", ")]}):null]})}function an({onReply:e}){const[n,r]=w(""),[o,i]=w(!1),[s,a]=w("");return t("form",{class:"composer",onSubmit:async c=>{c.preventDefault();const _=n.trim();if(!(!_||o)){i(!0),a("");try{await e(_),r("")}catch(d){a(d instanceof L?d.message:"Could not send that reply.")}finally{i(!1)}}},children:[t("label",{class:"field",children:[t("span",{children:"Reply"}),t("textarea",{rows:3,placeholder:"Write a reply…",value:n,disabled:o,onInput:c=>r(c.target.value)})]}),s&&t("p",{class:"err",children:s}),t("button",{class:"btn btn-primary",type:"submit",disabled:o||!n.trim(),children:o?"Sending…":"Reply"})]})}function cn({thread:e,onStatus:n,onReply:r,busy:o}){const i=e.attachments?.find(c=>c.kind==="screenshot")??e.attachments?.[0],s=e.anchor?.label??"",a=e.anchor??{};return t("article",{class:"detail detail-open",children:[t("div",{class:"detail-head",children:[t("span",{class:"key",children:e.key}),t("h1",{children:s||"A comment on this page"}),t("span",{class:`status status-${e.status}`,children:le[e.status]??e.status})]}),t("p",{style:"margin:6px 0 0;color:var(--ink-soft);font-size:13px",children:["Round ",e.roundNumber," · ",e.route||"/"," · left by ",e.createdBy.name||"someone"," ",Te(e.createdAt)]}),i?t("figure",{class:"shot",children:[t("img",{src:i.url,alt:`Screenshot of the page when ${e.key} was left`,width:i.width,height:i.height,loading:"lazy"}),t("figcaption",{children:["captured at ",i.width??"?"," × ",i.height??"?"]})]}):t("div",{class:"no-shot",children:[t("b",{children:"No screenshot for this one."}),t("p",{style:"margin:6px 0 0",children:"Either this instance had no bucket connected when it was left, or the reviewer turned the picture off for this comment. The anchor and the page context below are unaffected."})]}),t("section",{class:"thread",children:[e.comments.length===0&&t("p",{style:"color:var(--ink-soft)",children:"This thread has no readable comments."}),e.comments.map(c=>t("div",{class:"comment",children:[t("div",{class:"comment-head",children:[t("b",{children:c.author.name||"Anonymous"}),c.author.kind==="agent"&&t("span",{class:"agent",children:"agent"}),t("span",{style:"color:var(--ink-faint)",children:Te(c.createdAt)})]}),t("p",{children:c.body??t("i",{style:"color:var(--ink-faint)",children:"deleted"})})]},c.id))]}),t(an,{onReply:r}),t("section",{class:"block",children:[t("h2",{children:"Anchor"}),t("dl",{class:"kv",children:[t("dt",{children:"State"}),t("dd",{children:e.anchorState}),s&&t(N,{children:[t("dt",{children:"Label"}),t("dd",{children:s})]}),a.css&&t(N,{children:[t("dt",{children:"Selector"}),t("dd",{children:String(a.css)})]}),a.domid&&t(N,{children:[t("dt",{children:"DOM id"}),t("dd",{children:String(a.domid)})]}),a.page?.pathname&&t(N,{children:[t("dt",{children:"Path"}),t("dd",{children:String(a.page.pathname)})]})]})]}),t(ln,{context:e.context??{}}),t("div",{class:"actions",children:[e.status!=="resolved"?t("button",{class:"btn btn-primary",disabled:o,onClick:()=>n("resolved"),children:"Mark resolved"}):t("button",{class:"btn",disabled:o,onClick:()=>n("open"),children:"Reopen"}),e.status!=="progress"&&e.status!=="resolved"&&t("button",{class:"btn",disabled:o,onClick:()=>n("progress"),children:"In progress"}),a.page?.origin&&t("a",{class:"btn",href:`${a.page.origin}${a.page.pathname??"/"}?snag_t=${encodeURIComponent(e.key)}`,target:"_blank",rel:"noreferrer noopener",children:"Open on site ↗"})]})]})}function z(e){return e?new Date(e).toLocaleDateString(void 0,{day:"numeric",month:"short",year:"numeric"}):"—"}function dn({uid:e,rounds:n}){const[r,o]=w(null),[i,s]=w(""),[a,c]=w(null),[_,d]=w(null),[p,k]=w(""),[l,h]=w("14"),[m,y]=w(""),[b,f]=w(!1),g=()=>{o(null),I.listLinks(e).then(v=>o(v.data)).catch(v=>s(v instanceof L?v.message:"Could not load the links."))};M(()=>{c(null),s(""),g()},[e]);const T=async v=>{v.preventDefault();const u=p.trim();if(!(!u||b)){f(!0),s("");try{const S=Number(l),A=Number.isFinite(S)&&S>0?new Date(Date.now()+S*864e5).toISOString():void 0,$=await I.mintLink(e,{name:u,...A?{expiresAt:A}:{},...m?{roundId:m}:{}});c($),k(""),h("14"),y(""),g()}catch(S){s(S instanceof L?S.message:"Could not create that link.")}finally{f(!1)}}},R=async v=>{if(confirm(`Revoke "${v.name}"? Every session minted from it is out within 10 s. This cannot be undone — minting a new link is the recovery.`)){d(v.id),s("");try{await I.revokeLink(v.id),c(u=>u?.id===v.id?null:u),g()}catch(u){s(u instanceof L?u.message:"Could not revoke that link.")}finally{d(null)}}};return t("div",{class:"links",children:[t("div",{class:"links-list",children:[t("h1",{class:"links-title",children:"Review links"}),i&&t("p",{class:"err",children:i}),r===null&&t("p",{class:"empty",children:"Loading…"}),r?.length===0&&t("div",{class:"empty",children:[t("h2",{children:"No links yet"}),t("p",{children:"Mint one on the right — once this project needs a link, it is the only way a reviewer gets in."})]}),r&&r.length>0&&t("table",{class:"link-table",children:[t("thead",{children:t("tr",{children:[t("th",{children:"Name"}),t("th",{children:"Created"}),t("th",{children:"Expires"}),t("th",{children:"Last used"}),t("th",{children:"Uses"}),t("th",{})]})}),t("tbody",{children:r.map(v=>{const u=!!v.revokedAt,S=!u&&new Date(v.expiresAt).getTime()<=Date.now(),A=v.roundId?n?.find($=>$.id===v.roundId):null;return t("tr",{class:u||S?"link-dead":"",children:[t("td",{children:[v.name,A&&t("span",{class:"link-round",children:A.name})]}),t("td",{children:z(v.createdAt)}),t("td",{children:u?t("span",{class:"warn",children:["revoked ",z(v.revokedAt)]}):S?t("span",{class:"warn",children:"expired"}):z(v.expiresAt)}),t("td",{children:z(v.lastUsedAt)}),t("td",{children:v.useCount}),t("td",{children:!u&&t("button",{class:"btn",disabled:_===v.id,onClick:()=>void R(v),children:_===v.id?"Revoking…":"Revoke"})})]},v.id)})})]})]}),t("div",{class:"links-side",children:[a&&t("div",{class:"card minted",children:[t("h2",{children:['"',a.name,'" is ready']}),t("p",{class:"sub",children:["This is the only time the token is shown — the list on the left never carries it again. Paste it after the reviewed site's URL, e.g. ",t("code",{children:["https://yoursite.com/page",a.fragment]}),"."]}),t("div",{class:"token-box",children:[t("code",{children:a.fragment}),t("button",{class:"btn",onClick:()=>void navigator.clipboard.writeText(a.fragment).catch(()=>{}),children:"Copy"})]}),t("button",{class:"linkish",style:"margin-top:10px",onClick:()=>c(null),children:"Done"})]}),t("form",{class:"card",onSubmit:T,children:[t("h2",{children:"New link"}),t("label",{class:"field",children:[t("span",{children:"Name"}),t("input",{required:!0,placeholder:"Client review — round 2",value:p,onInput:v=>k(v.target.value)})]}),t("label",{class:"field",children:[t("span",{children:"Expires in (days, up to 90)"}),t("input",{type:"number",min:1,max:90,value:l,onInput:v=>h(v.target.value)})]}),n&&n.length>0&&t("label",{class:"field",children:[t("span",{children:"Pin to a round (optional)"}),t("select",{value:m,onChange:v=>y(v.target.value),children:[t("option",{value:"",children:"Any round"}),n.map(v=>t("option",{value:v.id,children:v.name},v.id))]})]}),t("button",{class:"btn btn-primary",type:"submit",disabled:b||!p.trim(),children:b?"Creating…":"Create link"})]})]})]})}function un({me:e,onAdded:n,origin:r}){const[o,i]=w(""),[s,a]=w(""),[c,_]=w(!1),[d,p]=w(""),[k,l]=w(null);return t("div",{class:"sites",children:[t("section",{class:"site-add",children:[t("h2",{children:"Add a site"}),t("form",{onSubmit:async m=>{if(m.preventDefault(),!c){_(!0),p("");try{const y=await I.createProject(o.trim(),s.trim());l({uid:y.uid,name:y.name,...y.warning?{warning:y.warning}:{}}),i(""),a(""),n(y.uid)}catch(y){p(y instanceof L?y.message:"Something went wrong. Try again.")}finally{_(!1)}}},children:[t("label",{children:["Name",t("input",{value:o,placeholder:"Acme redesign",onInput:m=>i(m.target.value),required:!0})]}),t("label",{children:["Where it runs",t("input",{value:s,placeholder:"https://staging.acme.com, http://localhost:3000",onInput:m=>a(m.target.value)}),t("small",{children:["Comma-separated, with the scheme. Only these can talk to the site — a tag on any other address is ignored. ",t("code",{children:"https://*.acme.com"})," covers subdomains."]})]}),t("button",{type:"submit",disabled:c||!o.trim(),children:c?"Adding…":"Add site"}),d&&t("p",{class:"error",children:d})]})]}),k&&t(_n,{site:k,origin:r}),t("section",{class:"site-list",children:[t("h2",{children:"Your sites"}),t("ul",{children:e.projects.map(m=>t("li",{children:[t("strong",{children:m.name}),t("code",{children:m.uid}),t("span",{children:[m.threads," snag",m.threads===1?"":"s"," · ",m.unresolved," open"]})]},m.uid))})]})]})}function _n({site:e,origin:n}){const[r,o]=w([]),[i,s]=w(""),[a,c]=w(""),[_,d]=w("everyone"),[p,k]=w(""),l=y=>{const b=_;d(y),k(""),I.setAudience(e.uid,y==="everyone"?"open":"link-required").catch(()=>{d(b),k("Could not save — try again.")})},h=He(()=>{I.origins(e.uid).then(y=>o(y.origins)).catch(()=>o([]))},[e.uid]);M(h,[h]);const m=`<script src="${n}/snag.js" data-snag-site="${e.uid}" defer><\/script>`;return t("section",{class:"site-made",children:[t("h2",{children:[e.name," is ready"]}),t("p",{children:"Paste this into the site, immediately before the closing </body> tag."}),t("div",{class:"site-audience",role:"radiogroup","aria-label":"Who sees the toolbar",children:[t("label",{children:[t("input",{type:"radio",name:"audience",checked:_==="everyone",onChange:()=>l("everyone")}),t("span",{children:[t("strong",{children:"Everyone on these addresses"})," — the toolbar just appears, and anyone can comment. For staging. Saved to the server: change it here any time, no re-paste."]})]}),t("label",{children:[t("input",{type:"radio",name:"audience",checked:_==="links",onChange:()=>l("links")}),t("span",{children:[t("strong",{children:"Only people with a review link"})," — visitors see nothing. For production, where the visitors are your client's customers."]})]}),p&&t("p",{class:"error",children:p})]}),t("pre",{children:t("code",{children:m})}),t("button",{class:"linkish",onClick:()=>{navigator.clipboard?.writeText(m)},children:"Copy"}),t("h3",{children:"Allowed origins"}),r.length?t("ul",{class:"origins",children:r.map(y=>t("li",{children:t("code",{children:y})},y))}):t("p",{class:"warn",children:e.warning??"None yet — the tag will load and every request from it will be refused. Add one below."}),t("form",{onSubmit:async y=>{y.preventDefault();const b=i.trim();if(b){c("");try{const f=await I.addOrigin(e.uid,b);o(f.origins),s("")}catch(f){c(f instanceof L?f.message:"Could not add that origin.")}}},children:[t("input",{value:i,placeholder:"https://www.acme.com",onInput:y=>s(y.target.value)}),t("button",{type:"submit",disabled:!i.trim(),children:"Allow"}),a&&t("p",{class:"error",children:a})]})]})}function hn(e,n,r=[]){const o=new Set(r),i=e.filter(s=>!o.has(s.id));for(const s of n){if(o.has(s.id))continue;const a=i.findIndex(c=>c.id===s.id);a===-1?i.push(s):i[a]=s}return i}function pn({token:e,onClaimed:n}){const[r,o]=w(""),[i,s]=w(""),[a,c]=w(""),[_,d]=w(""),[p,k]=w(!1),[l,h]=w(""),[m,y]=w(null);return m?t(mn,{site:m,onContinue:n}):t("div",{class:"setup",children:[t("h1",{children:"Set up Snagset"}),t("p",{class:"setup-lede",children:"This instance has not been claimed yet. The account you make here is the only one, until you add another."}),t("form",{onSubmit:async f=>{if(f.preventDefault(),!p){k(!0),h("");try{const g=await I.setup({token:e,orgName:r.trim()||"My studio",projectName:i.trim(),email:a.trim(),password:_});y(g.project)}catch(g){h(g instanceof L?g.message:"Something went wrong. Try again.")}finally{k(!1)}}},children:[t("label",{children:["Your email",t("input",{type:"email",value:a,autocomplete:"username",required:!0,onInput:f=>c(f.target.value)})]}),t("label",{children:["Password",t("input",{type:"password",value:_,autocomplete:"new-password",required:!0,minLength:12,onInput:f=>d(f.target.value)}),t("small",{children:"At least 12 characters. There is no reset email on a fresh install — keep it."})]}),t("label",{children:["Studio name ",t("span",{class:"setup-opt",children:"optional"}),t("input",{value:r,placeholder:"My studio",onInput:f=>o(f.target.value)})]}),t("label",{children:["First site ",t("span",{class:"setup-opt",children:"optional"}),t("input",{value:i,placeholder:"Acme redesign",onInput:f=>s(f.target.value)})]}),t("button",{type:"submit",disabled:p||!a.trim()||_.length<12,children:p?"Setting up…":"Create my account"}),l&&t("p",{class:"error",children:l})]})]})}function mn({site:e,onContinue:n}){const r=`<script src="${location.origin}/snag.js" data-snag-site="${e.uid}" defer><\/script>`;return t("div",{class:"setup",children:[t("h1",{children:[e.name," is ready"]}),t("p",{class:"setup-lede",children:"Paste this into the site you want reviewed, before the closing </body> tag."}),t("pre",{children:t("code",{children:r})}),t("div",{class:"setup-actions",children:[t("button",{type:"button",class:"linkish",onClick:()=>void navigator.clipboard?.writeText(r),children:"Copy"}),t("button",{type:"button",onClick:n,children:"Open the dashboard"})]}),t("p",{class:"setup-note",children:"The site's address has to be on its allow-list before comments can reach you — add it on the Sites screen. A tag on any other address loads and is ignored."})]})}const fn=["open","progress","review","resolved"],le={open:"Active",progress:"In progress",review:"In review",resolved:"Resolved"};function H(){const e=new URLSearchParams(location.search);return{project:e.get("project")??"",thread:e.get("t")??"",status:e.get("status")??"",q:e.get("q")??"",round:e.get("round")??"",screen:e.get("screen")??"",claim:e.get("claim")??""}}function Ae(e){const n={...H(),...e},r=new URLSearchParams;n.project&&r.set("project",n.project),n.thread&&r.set("t",n.thread),n.status&&r.set("status",n.status),n.q&&r.set("q",n.q),n.round&&r.set("round",n.round),n.screen&&r.set("screen",n.screen);const o=`${location.pathname}${r.toString()?`?${r}`:""}`;history.pushState(null,"",o)}function vn({onIn:e}){const[n,r]=w(""),[o,i]=w(""),[s,a]=w(""),[c,_]=w(!1);return t("div",{class:"gate",children:t("form",{class:"card",onSubmit:async d=>{d.preventDefault(),_(!0),a("");try{await I.login(n,o),e()}catch(p){a(p instanceof L?p.message:"Could not reach the server.")}finally{_(!1)}},children:[t("h1",{children:"Sign in"}),t("p",{class:"sub",children:"The studio side of Snagset. Reviewers do not sign in — they open a link."}),s&&t("p",{class:"err",children:s}),t("label",{class:"field",children:[t("span",{children:"Email"}),t("input",{type:"email",autocomplete:"username",required:!0,value:n,onInput:d=>r(d.target.value)})]}),t("label",{class:"field",children:[t("span",{children:"Password"}),t("input",{type:"password",autocomplete:"current-password",required:!0,value:o,onInput:d=>i(d.target.value)})]}),t("button",{class:"btn btn-primary",disabled:c,children:c?"Signing in…":"Sign in"}),t("p",{class:"sub",style:"margin:14px 0 0",children:["Forgotten it? There is no reset email on a fresh install — set a new one from the machine that runs the server: ",t("code",{children:"snagset passwd you@example.com"})]})]})})}function gn(){const[e,n]=w(null),[r,o]=w("loading"),[i,s]=w(H()),[a,c]=w(null),_=Ze(null),[d,p]=w(!1),[k,l]=w(null),[h,m]=w(null),y=He(async()=>{try{const u=await I.me();n(u),o("in"),!H().project&&u.projects[0]&&(Ae({project:u.projects[0].uid}),s(H()))}catch{o("out")}},[]);M(()=>{y(),fetch("/api/v1/meta").then(S=>S.json()).then(l).catch(()=>{});const u=()=>s(H());return addEventListener("popstate",u),()=>removeEventListener("popstate",u)},[y]);const b=i.project;M(()=>{if(r!=="in"||!b)return;let u=!0;return m(null),I.rounds(b).then(S=>u&&m(S.data)).catch(()=>u&&m([])),()=>{u=!1}},[r,b]);const f=i.round?Number(i.round):h?.[0]?.number??null;M(()=>{if(r!=="in"||!b||f===null)return;let u=!0;return c(null),I.threads(b,{round:f,...i.status?{status:i.status}:{},...i.q?{q:i.q}:{}}).then(S=>{u&&(c(S.data),_.current=S.serverTime)}).catch(()=>u&&c([])),()=>{u=!1}},[r,b,f,i.status,i.q]),M(()=>{if(r!=="in"||!b)return;let u=0;const S=()=>{if(document.hidden||!_.current)return;const A=Date.now();A-u<3e4||(u=A,I.threads(b,{...f===null?{}:{round:f},since:_.current,...i.status?{status:i.status}:{},...i.q?{q:i.q}:{}}).then($=>{_.current=$.serverTime,!(!$.data.length&&!$.deleted?.length)&&c(j=>j&&hn(j,$.data,$.deleted))}).catch(()=>{}))};return document.addEventListener("visibilitychange",S),()=>document.removeEventListener("visibilitychange",S)},[r,b,f,i.status,i.q]);const g=he(()=>a?.find(u=>u.key===i.thread)??null,[a,i.thread]),T=u=>{Ae(u),s(H())};if(r==="loading")return t("div",{class:"empty",children:"Loading…"});if(r==="out"&&i.claim)return t(pn,{token:i.claim,onClaimed:()=>void y()});if(r==="out")return t(vn,{onIn:()=>void y()});const R=async u=>{if(g){p(!0);try{const S=await I.setStatus(b,g.id,u);c(A=>A?.map($=>$.id===S.id?{...$,...S}:$)??A)}finally{p(!1)}}},v=async u=>{if(!g)return;const S=await I.addComment(g.id,u);c(A=>A?.map($=>$.id===g.id?{...$,comments:[...$.comments,S],commentCount:$.commentCount+1}:$)??A)};return t("div",{class:"shell",children:[t("header",{class:"topbar",children:[t("div",{class:"brand",children:["Snagset ",t("span",{children:"studio"})]}),t("select",{value:b,onChange:u=>T({project:u.target.value,thread:""}),children:e.projects.map(u=>t("option",{value:u.uid,children:[u.name," · ",u.unresolved," open"]},u.uid))}),h&&h.length>0&&t("select",{value:String(f??""),onChange:u=>T({round:u.target.value,thread:""}),children:h.map(u=>t("option",{value:String(u.number),children:[u.name,u.closed?" (closed)":""," · ",u.unresolved," open"]},u.id))}),t("button",{class:"linkish",title:"Start a new round. The page goes clean; nothing is deleted.",onClick:async()=>{const u=(h?.[0]?.number??0)+1,S=prompt("Name for the new round",`Round ${u}`);if(S===null)return;const A=await I.createRound(b,S).catch(()=>null);if(!A)return;const $=await I.rounds(b).catch(()=>null);$&&m($.data),T({round:String(A.number),thread:""})},children:"+ Round"}),t("button",{class:"linkish","aria-pressed":i.screen==="links",onClick:()=>T({screen:i.screen==="links"?"":"links",thread:""}),children:"Links"}),t("button",{class:"linkish","aria-pressed":i.screen==="sites",onClick:()=>T({screen:i.screen==="sites"?"":"sites",thread:""}),children:"Sites"}),t("div",{class:"spacer"}),t("span",{class:"who",children:e.user.email}),t("button",{class:"linkish",onClick:async()=>{await I.logout().catch(()=>{}),o("out")},children:"Sign out"})]}),i.screen==="sites"?t(un,{me:e,origin:location.origin,onAdded:async u=>{const S=await I.me().catch(()=>null);S&&n(S),T({project:u,thread:""})}}):i.screen==="links"?t(dn,{uid:b,rounds:h}):t(N,{children:[h&&f!==null&&t(N,{children:h.filter(u=>u.number!==f&&u.unresolved>0).map(u=>t("button",{class:"carryover",onClick:()=>T({round:String(u.number),thread:""}),children:[t("b",{children:[u.unresolved," unresolved"]})," in ",u.name," — still open, not carried over. Go there ↗"]},u.id))}),t("div",{class:"inbox",children:[t("div",{class:"list",children:[t("div",{class:"filters",children:[t("input",{type:"search",placeholder:"Search comments",value:i.q,onInput:u=>T({q:u.target.value})}),fn.map(u=>t("button",{class:"chip","aria-pressed":i.status===u,onClick:()=>T({status:i.status===u?"":u}),children:le[u]},u))]}),t("div",{class:"rows",children:[a===null&&t("p",{class:"empty",children:"Loading…"}),a?.length===0&&t("div",{class:"empty",children:[t("h2",{children:"Nothing here"}),t("p",{children:i.q||i.status?"No comment matches that filter.":"No comments on this project yet. Paste the script tag on the site and click something."})]}),a?.map(u=>t("button",{class:"row","aria-current":u.key===i.thread,onClick:()=>T({thread:u.key}),children:[t("div",{class:"row-top",children:[t("span",{class:"key",children:u.key}),t("span",{class:`status status-${u.status}`,children:le[u.status]})]}),t("p",{class:"row-body",children:u.comments[0]?.body??u.anchor?.label??"(no comment)"}),t("div",{class:"row-meta",children:[t("span",{children:u.route||"/"}),t("span",{children:"·"}),t("span",{children:u.createdBy.name||"someone"}),u.attachments?.length?t("span",{children:"· 📷"}):null]})]},u.id))]})]}),g?t(cn,{thread:g,onStatus:u=>void R(u),onReply:v,busy:d}):t("div",{class:"empty",children:[t("h2",{children:"Pick a comment"}),t("p",{children:"Its screenshot, the thread, the anchor and the page context all open here."})]})]})]}),t("footer",{class:"foot",children:[t("span",{children:[e.org.name," · ",k?.version??"…"]}),k?.commit&&t("span",{children:k.commit.slice(0,8)})]})]})}Ye(t(gn,{}),document.getElementById("app"));
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
<meta charset="utf-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<meta name="color-scheme" content="light dark" />
|
|
7
|
+
<link rel="icon" href="/mark.svg" type="image/svg+xml" />
|
|
7
8
|
<title>Snagset</title>
|
|
8
|
-
<script type="module" crossorigin src="/assets/index-
|
|
9
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
9
|
+
<script type="module" crossorigin src="/assets/index-DultqpS7.js"></script>
|
|
10
|
+
<link rel="stylesheet" crossorigin href="/assets/index-DsUJ96yc.css">
|
|
10
11
|
</head>
|
|
11
12
|
<body>
|
|
12
13
|
<div id="app"></div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" role="img" aria-label="Snagset">
|
|
2
|
+
<!--
|
|
3
|
+
D78. The pin at rest on a rule: the shipped pin (a circle of r 12 with its
|
|
4
|
+
lower-left quadrant squared — the same construction as
|
|
5
|
+
`border-radius: 50% 50% 50% 2px` in pins.ts) floating 4.3 units above a
|
|
6
|
+
full-bleed rule.
|
|
7
|
+
|
|
8
|
+
Three things are load-bearing and must not be tidied:
|
|
9
|
+
· the pin FLOATS — it has not landed; touching the rule parks it
|
|
10
|
+
· the composition is ASYMMETRIC — 8 units of rule run on past the pin,
|
|
11
|
+
which is what says `page` rather than `underline`
|
|
12
|
+
· the pin's sharp corner and the rule's left end share x 0, the one
|
|
13
|
+
alignment, which reads only because nothing else lines up
|
|
14
|
+
|
|
15
|
+
Stroke weight, colour and file preparation are in scope for a refinement.
|
|
16
|
+
Position, scale and alignment are the composition.
|
|
17
|
+
-->
|
|
18
|
+
<style>
|
|
19
|
+
:root { color-scheme: light dark; }
|
|
20
|
+
path { fill: #181716; stroke: #181716; }
|
|
21
|
+
@media (prefers-color-scheme: dark) { path { fill: #f0eeec; stroke: #f0eeec; } }
|
|
22
|
+
</style>
|
|
23
|
+
<path d="M0 24V12A12 12 0 0 1 12 0a12 12 0 0 1 12 12 12 12 0 0 1-12 12z" stroke="none"/>
|
|
24
|
+
<path d="M0 30h32" fill="none" stroke-width="3.4" stroke-linecap="square"/>
|
|
25
|
+
</svg>
|