From a8420fe005aa41e69413222072a6e072cab1f7e7 Mon Sep 17 00:00:00 2001 From: "planetrenox@protonmail.com" Date: Thu, 15 Oct 2026 16:35:39 +0000 Subject: [PATCH] Feat: Serve max-i.webp for ?i= past the limit, and allow up to 1000 on ai.* max-i.webp lists each site's range (40 main, 20 free, 1000 ai) and is drawn in code from design/max-i.html. Other invalid ?i= values still serve bad.webp. Co-Authored-By: Claude Opus 5.5 --- README.md | 8 ++++---- assets/max-i.webp | Bin 0 -> 13686 bytes design/max-i.html | 38 ++++++++++++++++++++++++++++++++++++++ functions/[[path]].js | 15 +++++++++------ index.html | 2 +- 5 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 assets/max-i.webp create mode 100644 design/max-i.html diff --git a/README.md b/README.md index 7dfd201..d5e9324 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Add `?i=` to serve a later search result instead of the first, e.g. when the fir https://direct-img.link/orange+cat?i=2 ``` -- `i` is `1`–`40`, default `1`. Invalid values serve `bad.webp` +- `i` is `1`–`40`, default `1`. Higher values serve `max-i.webp`, which lists each site's range, and other invalid values serve `bad.webp` - Leading zeros are ignored (`?i=02` = `?i=2`) - Only images that download count, so broken links and deleted photos are skipped and every `i` is a different image. `?i=2` is the 2nd working image - Higher `i` values take a little longer the first time, since the working images before it are downloaded to count them @@ -104,7 +104,7 @@ Need images you can publish? `free.direct-img.link` only serves images marked ** | `i` | `1`–`20` — works the same as [on the main site](#picking-a-result) | `1` | - Both are optional and can be used alone or together, in any order (`?i=2&src=wikimedia` = `?src=wikimedia&i=2`) -- Invalid values serve `bad.webp` +- `i` above `20` serves `max-i.webp`, which lists each site's range. Other invalid values serve `bad.webp` - With a `src`, only that source's images are served: if it has no image (or fewer than `i` working ones), `bad.webp` is served (remembered for 24h) instead of an AI image. Without one, an AI image is served like on the main site - Each `src` + `i` + query combination is cached separately. Like the main site, other `i` values within an hour of a search reuse its results and don't count as searches @@ -128,10 +128,10 @@ Licenses come from each source's metadata and can be wrong. Check the original b | Param | Values | Default | |---|---|---| | `src` | `auroraimg-6m` (case-insensitive) | `auroraimg-6m` | -| `i` | `1`–`20` — each is a different image of the same query | `1` | +| `i` | `1`–`1000` — each is a different image of the same query | `1` | - The same query, `src` and `i` always give the same image -- Invalid values serve `bad.webp` +- `i` above `1000` serves `max-i.webp`, which lists each site's range. Other invalid values serve `bad.webp` - Images come from [AuroraIMG-6M](https://github.com/direct-img/AuroraIMG-6M), a tiny 6.8M-parameter model running on our own server. They're 512px, soft and painterly: the right colors, setting and mood, but often not the exact object, and faces come out distorted - The same model makes the fallback images for searches that find nothing diff --git a/assets/max-i.webp b/assets/max-i.webp new file mode 100644 index 0000000000000000000000000000000000000000..97a113286904a6fc473e52761e4a30636644ac2b GIT binary patch literal 13686 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 literal 0 HcmV?d00001 diff --git a/design/max-i.html b/design/max-i.html new file mode 100644 index 0000000..bb0c46b --- /dev/null +++ b/design/max-i.html @@ -0,0 +1,38 @@ + + + + + + + + + +
?i=
+
+

That ?i= is too high

+ + + + +
direct-img.link1–40
free.direct-img.link1–20
ai.direct-img.link1–1000
+
+ + diff --git a/functions/[[path]].js b/functions/[[path]].js index 0253571..0a84deb 100644 --- a/functions/[[path]].js +++ b/functions/[[path]].js @@ -6,8 +6,10 @@ import { aiImage, parseAiSource, DEFAULT_AI_SOURCE } from "./_utils/ai.js"; import * as LIMITS from "../assets/rate-limit.js"; const TTL_SECONDS = 90 * 24 * 60 * 60; -// Highest ?i= per site: 40 on the main site (100 Brave results), 20 on free.* (~50 Openverse + Wikimedia results) and ai.* -const MAX_INDEX = { "": 40, free: 20, ai: 20 }; +// Highest ?i= per site: 40 on the main site (100 Brave results), 20 on free.* (~50 Openverse + Wikimedia +// results) and 1000 on ai.* (each is a new image, so there's no list to run out). +// Higher values serve max-i.webp, which lists these, so redraw it from design/max-i.html when they change. +const MAX_INDEX = { "": 40, free: 20, ai: 1000 }; // How long a search may hold its query's lock; longer than the 20s image deadline plus the search itself const LOCK_SECONDS = 45; // How long a search's results are kept for the query's other ?i=, which then don't search again or count toward limits @@ -44,10 +46,11 @@ export async function onRequest(context) { const site = ["free", "ai"].find(s => url.hostname.startsWith(`${s}.`)) || ""; const free = site === "free", ai = site === "ai"; const label = { free: "Free ", ai: "AI " }[site] || ""; - const i = parseIndex(url.searchParams, MAX_INDEX[site]); + const i = parseIndex(url.searchParams); const src = free ? parseFreeSource(url.searchParams) : ai ? parseAiSource(url.searchParams) : null; const extra = [...url.searchParams.keys()].some(k => k !== "i" && !(site && k === "src")); if (!i || (site && !src) || extra) return asset("bad.webp"); + if (i > MAX_INDEX[site]) return asset("max-i.webp"); context.waitUntil(countHit(env, request, query, site)); @@ -279,10 +282,10 @@ COMMIT TRANSACTION;`; return job; } -// ?i=1..max (default 1). Returns null if invalid. -function parseIndex(searchParams, max) { +// ?i=1 or higher (default 1). Returns null if invalid. +function parseIndex(searchParams) { const i = searchParams.get("i") || "1"; - return /^\d+$/.test(i) && +i >= 1 && +i <= max ? +i : null; + return /^\d+$/.test(i) && +i >= 1 ? +i : null; } // Brave results, or Bing's if Brave has none or refuses (e.g. once its spending limit is hit). null if Bing fails too, diff --git a/index.html b/index.html index 0c5849d..4f37d43 100644 --- a/index.html +++ b/index.html @@ -110,7 +110,7 @@ Use images to complement your responses, powered by Brave. srcauroraimg-6mauroraimg-6m - i1–20 (a different image each)1 + i1–1000 (a different image each)1

* The same query always gives the same image. When a search on direct-img.link or free.direct-img.link (without src) finds nothing, an AI image is served instead. Made with AuroraIMG-6M.