Jamorham
Nightscout용 xDrip+ 버전
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Adaptive reading for ADHD, dyslexia and cognitive fatigue. NeuroLens takes dense
text — a PDF, an EPUB, a pasted chapter — and reshapes it into something calmer
to get through: bionic fixation, adjustable rhythm and spacing, a reading mask, a
word guide, and a set of palettes designed for low vision rather than for looks.
Live at neurolens.space.
Two environment variables are required. Without them the app renders a single
screen saying so, rather than a sign-in page that cannot work:README 전문 보기 ↗Adaptive reading for ADHD, dyslexia and cognitive fatigue. NeuroLens takes dense text — a PDF, an EPUB, a pasted chapter — and reshapes it into something calmer to get through: bionic fixation, adjustable rhythm and spacing, a reading mask, a word guide, and a set of palettes designed for low vision rather than for looks.
Live at neurolens.space.
npm install
cp .env.example .env.local # then fill in the two Supabase values
npm run dev # http://localhost:8080
Two environment variables are required. Without them the app renders a single screen saying so, rather than a sign-in page that cannot work:
| Variable | What it is |
|---|---|
VITE_SUPABASE_URL | https://<project-ref>.supabase.co |
VITE_SUPABASE_ANON_KEY | The project's anon key |
VITE_SITE_URL | Optional. The canonical origin, for SEO and sitemaps. |
The anon key belongs in the browser. It is designed to be public, and it is
row-level security in the database — not the secrecy of that key — that decides
who can read what. Every table is enable row level security with policies
comparing auth.uid() to user_id; see supabase/migrations/.
If those policies are ever dropped, the key becomes an open door.
npm run check:env confirms the project is reachable and the key is accepted.
Worth running when sign-in misbehaves — it exists because a one-letter typo in a
deployed environment variable (superbase.co) broke authentication in production
while every local check passed.
| Command | What it does |
|---|---|
npm run dev | Dev server on port 8080 |
npm run build | Production build |
npm test | Unit tests — Node's own runner, no framework |
npm run test:a11y | Accessibility audit in a real browser (axe + Playwright) |
npm run typecheck | tsc --noEmit |
npm run lint | ESLint |
npm run check:env | Is Supabase reachable, and is the key accepted? |
node scripts/audit-themes.mjs | Contrast check on all 15 palettes (--fix applies) |
src/
components/ UI. app-shell.tsx is the frame; reader.tsx is the reader.
lib/
store.ts Zustand. One store, all reading state.
sync/ Offline-first Supabase sync — see below.
telemetry/ Analytics and crash reports, both schema-locked.
adaptive/ The engine that adjusts pace and spacing while you read.
seo.ts Per-route metadata and structured data.
routes/ TanStack Start file routes. api/* are server handlers.
scripts/ Build steps, audits and one-off maintenance tools.
supabase/migrations/ The schema, including every RLS policy.
tests/ Browser tests. Accessibility only, on purpose.
Stack. React 19, TanStack Start/Router, Zustand, Tailwind v4, Vite 8, Supabase (Postgres + Google OAuth), deployed on Vercel.
Reading works offline and syncs when it can, so the data layer is not a thin wrapper over the database. Worth knowing before changing it:
sync/queue.ts collapses repeated writes to
the same target, so dragging a slider is one row, not two hundred.sync/identity.ts maps between them. Two books that open
with the same licence header collide under the local scheme, which is the whole
reason the second scheme exists.localStorage is namespaced per account (sync/../storage-scope.ts).
Without it, two people on one device saw each other's library. Note that
signing out does not clear it: somebody who declined to upload their books
keeps them only there.sent, gone or defer. It used to return
nothing on failure, which read as success and dequeued the write — highlights
were being destroyed silently.The privacy policy is meant to be checkable against the source rather than taken on trust, so most of its claims are enforced somewhere specific:
src/lib/analytics.ts — every event is checked against
a fixed schema and each field accepts only values from a closed list. There is
no free-text field, so a book's contents cannot be recorded even by mistake.src/lib/telemetry/errors.ts — crash messages
are rewritten before sending: quoted text, URLs, addresses and numbers are
replaced. The tests are mostly hostile
inputs, because they are the privacy claim.supabase/migrations/0002_telemetry.sql —
the telemetry tables grant insert and nothing else. Not even the app can read
them back through the API. Retention is a pg_cron job, not a promise.This is the product, not a checklist. npm run test:a11y runs axe against every
public page at WCAG 2.2 AA on each push, and scripts/audit-themes.mjs checks
all fifteen palettes arithmetically — a browser test only ever measures whichever
one happened to be loaded.
Both found real faults when first written: eight palettes whose small print sat
between 3.88:1 and 4.34:1, and a reduced-motion rule that left text at
opacity: 0 until an observer fired, so a reader who asked for less motion got
invisible paragraphs.
Three ways, and one deliberate absence.
lib/opds/) — the open standard for book
catalogues. Calibre-Web, Kavita, Komga, Standard Ebooks and many public
libraries publish one, so "connect your library" means a reader's own server.My Clippings.txt (lib/import/) — every
Kindle writes one to its own storage. Highlights are anchored into the
matching book where it is in the library, and kept as notes where it is not.Kindle, Libby and Hoopla cannot be integrated, and the reason is not effort. None publishes an API for third-party reading apps, and their catalogues are behind DRM that only their own clients may open. Anything that appeared to work would be scraping, would break on their next deploy, and would breach their terms. OPDS and the clippings file are the honest paths to the same value: the reader's own books, and the reader's own marks.
/api/opds is the one endpoint here that fetches a URL somebody typed, which
makes it the one that could become a request forger. See
lib/opds/safe-url.ts — https only, no credentials,
no private address by literal or by DNS, no redirects followed, response
capped. The tests beside it are written as attacks rather than as edge cases.
Everything in public/images/ is AI-generated — no
photographs, no real people, no stock licences, nothing to attribute. See
public/images/CREDITS.md, which also explains why
the "How it lands" section on the landing page is written in the present tense:
a generated portrait beside a past-tense claim reads as a customer testimonial,
and there are no customers being quoted.
npm install prunes @rolldown/binding-win32-x64-msvc, and the build then
fails. Restore it with npm install --no-save @rolldown/binding-win32-x64-msvc.
Do not add it to package.json — it is the wrong platform for CI.MSYS_NO_PATHCONV=1 when passing something like /auth/v1/settings.MIT.