iArt.ai
AI 모션 그래픽 소프트웨어, 누구나 사용할 수 있는 After Effects 대안, 텍스트 프롬프트로 몇 분 안에 애니메이션·설명 영상 제작
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
A single-page daily dashboard in an editorial / broadsheet style: weather for Singapore, Tokyo, Vancouver, and Whistler, live market quotes, AI-written tech & lifestyle news with links to the original articles, Strava mileage, and a quote of the day — gathered fresh each morning. Built as one static page plus a few Vercel serverless functions. No framework, no build step. [README 설치·사용 부분 발췌] Setup (one-time): in Google Cloud Console → APIs & Services → Credentials, create an OAuth client ID (Web application) with https://marktan.ai as an authorized JavaScript origin, then set `GOOGLREADME 전문 보기 ↗
A single-page daily dashboard in an editorial / broadsheet style: weather for Singapore, Tokyo, Vancouver, and Whistler, live market quotes, AI-written tech & lifestyle news with links to the original articles, Strava mileage, and a quote of the day — gathered fresh each morning.
Built as one static page plus a few Vercel serverless functions. No framework, no build step.
| Section | Source | Needs a key? |
|---|---|---|
| Projects bar | PROJECTS array in index.html | No |
| Markets (8 quotes, 5-day sparklines with date spans; gold also in S$/kg) | Yahoo Finance chart API | No |
| Exchange rates (USD→SGD, USD→JPY, SGD→JPY, SGD→CAD, USD→CAD) | Yahoo Finance chart API | No |
| Weather (Singapore, Tokyo, Vancouver, Whistler — incl. rain chance & US AQI; Whistler adds a Nov–Apr snow report) | Open-Meteo forecast + air-quality APIs | No |
| Stories & Briefs (deep-linked to the desk) | The day's MERIDIAN edition — feed.json from github.com/markt1600/dailymag (dailymag.marktan.ai). No web search here. | No |
| Quote of the Day + edition provenance line | MERIDIAN's "From the Desk" quote (same feed.json) | No |
| MERIDIAN pipeline tile (header) — green "No. N · built 06:47 · 24pp · QA clean", red past 07:15 SGT if today's issue hasn't landed, grey before that | status.json from github.com/markt1600/dailymag, committed by each build after its QA gate; re-checked every 10 min | No |
| Sports · Last 24 Hours (only while a major event is on — World Cup, Grand Slams, Tour de France, Olympics, late playoff rounds, F1…) | Claude + web search (/api/sports) | ANTHROPIC_API_KEY |
| Fitness (24h / 7d / 30d distance & run pace) | Strava API | Strava env vars |
| COE premiums (latest bidding exercise, all 5 categories) | LTA dataset via data.gov.sg API | No |
| Account balances (ElevenLabs credits, Claude API 30-day spend) — inside the owner-only For Mark · Private section | ElevenLabs + Anthropic Admin APIs | See below |
| Happy Day counter (relationship day count, ticks over at midnight SGT) | HAPPY_DAY config in index.html | No |
| Birthdays (owner-only, shown 7 days before → 3 days after in the For Mark section) | encrypted store data/birthdays.enc.json — edit at /admin | Login |
| Events watchlist (concerts, races, fitness, motorsport — finished events drop off) | data/events.json — edit at /admin (inline EVENTS array in index.html is the fallback) | No |
| Personal calendar (owner-only): Outlook-style month/week views, Sunday-first, multi-day events as continuous bars, recurring events (weekly/monthly/yearly), birthdays as annual dots; click any entry to edit every field or delete it (saves through the admin APIs with a fresh-sha conflict guard) | Public events + birthdays + the encrypted private list (/api/private-events) | Login |
Statement filing + recurring to-dos (owner-only): on schedule the daily cron adds items to the to-do list — statement-filing days and monthly bills are built in, and any item can be made recurring (monthly/yearly on a chosen date) from the To-dos panel in /admin | STATEMENTS / MONTHLY_TODOS configs in api/notify.js; user rules stored encrypted with the list | Login |
| Public holidays (next per region: Singapore, Japan, Vancouver/BC, Hong Kong, Shanghai) | Nager.Date API | No |
| 🔔 Morning digest push (07:20 SGT: build status, birthdays, event starts) | Web Push via /api/notify cron — see Notifications below | VAPID keys |
Sections whose keys aren't configured simply hide themselves — the page is never empty.
Account balances live inside the owner-only For Mark · Private section and appear only while logged in (below).
Owner login (Google Sign-In): the footer has a small login link that swaps itself for Google's sign-in button. api/login.js verifies the Google ID token (signature/expiry via Google's tokeninfo endpoint, audience must match GOOGLE_CLIENT_ID, and the verified email must be the owner's — any other Google account gets 403) and mints a 90-day HMAC session (api/_session.js, keyed off SESSION_SECRET → ADMIN_SECRET → DASHBOARD_SECRET). The session lives in localStorage and is re-verified server-side on every load. While logged in, the body gets the owner class, any element with class owner-only becomes visible (there's a "For Mark · Private" placeholder section wired up), the balances inside it are fetched with the session token, and /admin opens automatically. logout clears the session. Logged-out visitors see the page exactly as before.
Setup (one-time): in Google Cloud Console → APIs & Services → Credentials, create an OAuth client ID (Web application) with https://marktan.ai as an authorized JavaScript origin, then set GOOGLE_CLIENT_ID in Vercel. Until it's set, the login link explains it isn't configured yet.
index.html — the whole frontend. Fetches /api/dashboard, /api/fitness, and /api/balances and renders them. If the dashboard call fails (e.g. opening the file locally), it falls back to a sample edition instead of breaking.api/dashboard.js — weather, markets, FX, holidays, and the day's edition. The Stories & Briefs come from MERIDIAN: it fetches feed.json from github.com/markt1600/dailymag (published each morning ~7am SGT), maps the desk leads into features (MERIDIAN's cover-teaser top picks) + briefs, and deep-links each back to its desk at dailymag.marktan.ai. No web search runs here — the research is MERIDIAN's. If today's feed hasn't published yet, the raw file is simply the most recent edition (the "last good" stories, dated in the provenance line).api/sports.js — major-event sports results. Its own endpoint (and a cron an hour after the news one) so the two web-search Claude calls never share a rate-limit minute; returns an empty list when nothing major is on, and the section hides itself.api/fitness.js — Strava summary. Exchanges a long-lived refresh token for an access token on each run; cached ~1h.api/balances.js — ElevenLabs credits + Claude API 30-day spend. Never cached. Gated: with DASHBOARD_SECRET set, requests need a valid owner login session (Google Sign-In); without the secret set, it's public.api/admin.js — backend for the admin editor. Auth: the owner's Google-login session, or the shared automation secret (ADMIN_SECRET / DASHBOARD_SECRET) for scripted access. GET returns the current lists; POST commits an edited list to data/*.json via the GitHub Contents API (needs GITHUB_TOKEN). Each save is a commit, so git history is the audit trail; the current blob sha is round-tripped so a concurrent edit 409s instead of silently clobbering.data/events.json — the authoritative Events list the dashboard fetches. Edited through /admin; the inline array in index.html remains as an offline/local-preview fallback. Birthdays live in the encrypted data/birthdays.enc.json (personal info — owner-only, served via /api/private-events).api/assist.js — the admin page's Claude calendar assistant: takes free-form text, a pasted screenshot, or an uploaded file (image, PDF sent as a native document block, or .docx/.txt/.csv/.ics/.md/.eml — Word text is extracted in the browser, no libraries) plus both event lists, returns proposed adds (routed public/private) and deletions for review. Nothing commits until the owner confirms — confirming saves the ticked changes straight to the relevant list(s); the manual Save buttons are only for edits made directly in the tables. Uses .The site is an installable PWA (manifest.json + sw.js) that can deliver a 07:20 SGT morning digest to your lock screen with the browser closed: MERIDIAN build status (or a ⚠ if it hasn't published), birthdays today/tomorrow/in a week, and watchlist events starting today or tomorrow.
api/push.js (GET = VAPID public key; POST = register/remove a device), api/notify.js (composes + sends the digest; cron 20 23 * * * UTC = 07:20 SGT; ?token=<ADMIN_SECRET>&dry=1 previews without sending), sw.js (receives pushes; the tag field means re-sends replace rather than stack).data/push-subs.enc.json — committed to this public repo, so they're AES-256-GCM encrypted at rest (key derived from PUSH_STORE_KEY, falling back to VAPID_PRIVATE_KEY); endpoints are private capability URLs and never appear in plaintext./api/notify additionally rejects callers without CRON_SECRET (sent automatically by Vercel's cron) or the admin token./admin)Editing Birthdays and Events no longer means touching index.html. Visit /admin — it opens only for the owner's Google login (sign in on the dashboard first); there is no password. Edit both lists in a table UI. There's also a direct link in the For Mark · Private section. Saving commits to GitHub (data/events.json in plaintext; birthdays into the encrypted data/birthdays.enc.json) — which is the version history — and the change goes live once Vercel finishes the redeploy triggered by that commit (~a minute). The dashboard fetches events at load (inline-array fallback); birthdays arrive only with the owner login.
Requires two env vars (below): ADMIN_SECRET (the API automation secret) and GITHUB_TOKEN (fine-grained, Contents: Read & Write on markt1600/mainpage) so the function can read and commit. If neither ADMIN_SECRET nor DASHBOARD_SECRET is set, the admin APIs refuse to run — nothing ever opens unprotected.
/api/dashboard is edge-cached for ~24 hours (s-maxage=86400). The Stories & Briefs no longer run a paid web search — they're a cheap fetch of MERIDIAN's feed.json — so the daily cost is essentially just the sports call. The cron (15 23 * * * UTC = 07:15 SGT) warms the cache after MERIDIAN publishes (it builds ~06:00–07:00 SGT), so the morning edition reflects that day's MERIDIAN. The "↻ new stories" link in the footer forces a fresh, uncached fetch on demand.
Set these in Vercel → Settings → Environment Variables:
| Variable | Used by | Notes |
|---|---|---|
ANTHROPIC_API_KEY | sports.js | From https://console.anthropic.com. Now used only by the sports function; the dashboard's Stories & Briefs come from MERIDIAN and need no key. |
STRAVA_CLIENT_ID, STRAVA_CLIENT_SECRET, STRAVA_REFRESH_TOKEN | fitness.js | Refresh token from a one-time OAuth authorization with scope activity:read_all. |
ELEVENLABS_API_KEY | balances.js | elevenlabs.io → Profile → API key. |
ANTHROPIC_ADMIN_KEY | balances.js | Admin key (sk-ant-admin…) from console → Settings → Organization → Admin keys. Not the same as ANTHROPIC_API_KEY. |
DASHBOARD_SECRET | balances.js, admin.js | Optional. If set, balances are gated behind the owner login; also the fallback for ADMIN_SECRET as the API automation credential (shortcuts); /admin itself is Google-login only. |
ADMIN_SECRET | admin.js | Shared automation secret for API access from scripts/shortcuts (never a way into the /admin page, which is Google-login only). Falls back to DASHBOARD_SECRET; if neither is set, the admin APIs refuse to run. |
GITHUB_TOKEN | admin.js, push.js, notify.js | Fine-grained personal access token with Contents: Read & Write on markt1600/mainpage. Lets /admin and the push endpoints read and commit data/*.json. Server-only. Optional: GITHUB_REPO / GITHUB_BRANCH override the defaults markt1600/mainpage / main. |
MERIDIAN_DELIVER_TOKEN | deliver.js | Fine-grained personal access token with Actions: Read & Write on markt1600/dailymag. Lets the magazine's "⇥ reMarkable" menu item fire the delivery workflows ( / ) on demand. Until it's set the endpoint 502s and the menu item falls back to opening the GitHub Actions page. Optional: / override / . |
Keys live only in the serverless functions and are never sent to the browser.
Option A — GitHub + Vercel dashboard (easiest)
ANTHROPIC_API_KEY).Option B — Vercel CLI
npm i -g vercel
vercel # first deploy (preview)
vercel env add ANTHROPIC_API_KEY production
vercel --prod # deploy to production
In index.html:
PROJECTS array near the top of the <script>; each entry is { name, url }./admin (writes the encrypted data/birthdays.enc.json; owner-only on the site). Each entry is { name, month, day }. They appear in the For Mark section and in the personal calendar as small annual dot items./admin (writes data/events.json). Each entry is { act, kind, date, endDate, time, repeat, venue, status, note, url } where kind is a short type label ("Concert", "Race", "Fitness", "Motorsport", …) shown on the card, time is an optional HH:MM (24h) shown on the card and used for the timed calendar download, repeat is an optional "weekly" | "monthly" | "yearly" that makes the entry recur in the personal calendar (occurrences keep the original's duration; dates that don't exist — the 31st in a short month, Feb 29 — are skipped) and adds an RRULE to the calendar download, and date: null marks it TBA. Past events disappear automatically. The inline EVENTS array here is only the offline fallback.COST_BASIS map (Yahoo symbol → average buy-in price) draws a green border around a market tile when the live price is at/above your average and a red border when below.HAPPY_DAY constant holds the anniversary (month, day) and firstYear. The display reads <completed years × 365>.<day of the current relationship year>, with day 1 on the anniversary, resetting each year at midnight Singapore time.In api/dashboard.js:
MODEL defaults to claude-haiku-4-5-20251001 (fast, cheap). Swap for a Sonnet model for richer prose.CITIES array (name, lat/lon, timezone). Panels render top-to-bottom in array order.MARKETS array (display label + Yahoo Finance symbol).FX_PAIRS array (Yahoo symbols like SGDJPY=X).HOLIDAY_REGIONS (Nager.Date country codes; optional subdivision like CA-BC).allowed_domains list; the prompt (SCHEMA_PROMPT) asks for 5 briefs + 3 features.s-maxage=86400 in the Cache-Control header and the cron schedule in vercel.json.Opening index.html directly (or serving it statically) works — it shows the sample edition since /api/* isn't running. To exercise the real functions locally, run vercel dev with your env vars available.
maxDuration is 60s to allow for it. Thanks to stale-while-revalidate, visitors almost always get the instant cached copy.http(s) URLs on both the server and the client; a story without a usable URL renders unlinked rather than guessing.ANTHROPIC_API_KEYapi/special.js — serves MERIDIAN's owner-only special editions. Specials live encrypted at rest in the public dailymag repo (X25519 sealed-box .enc blobs); this endpoint fetches a blob from raw.githubusercontent, decrypts it with MERIDIAN_SPECIALS_KEY, and serves it only to a valid owner session (the .marktan.ai mt_owner cookie or ?token=). Everyone else gets a plain 404 — never a 401 — so the specials don't observably exist. PDFs over ~4.4 MB get a "delivered to your reMarkable" note instead (Vercel response cap).api/todos.js — Mark's private to-do list, encrypted at rest exactly like the private calendar (data/todos.enc.json, AES-256-GCM). GET returns the list + sha; POST {todos, sha} saves with a conflict guard; POST {add: "text"} is a sha-free server-side append used by the dashboard's quick-add box, the /todo voice page, and phone/watch shortcuts. Auth: owner session or admin secret. Shortcuts must call https://www.marktan.ai/... — the apex domain redirects to www, and Apple Shortcuts drops the POST body when following that redirect (the request degrades to a harmless GET).api/transcribe.js — voice → text for /todo's hold-to-record button, via ElevenLabs Speech-to-Text (Scribe; reuses ELEVENLABS_API_KEY). The browser records a clip and POSTs it; the transcript comes back and is added via /api/todos.api/private-events.js — the private calendar list (travel, personal items). Committed as data/private-events.enc.json, AES-256-GCM encrypted (key: PRIVATE_STORE_KEY → PUSH_STORE_KEY → VAPID_PRIVATE_KEY) since the repo is public; GET/POST gated by the owner session or admin secret, with sha-guarded writes.admin.html (served at /admin) — a self-contained CRUD editor: add/edit/delete rows in tables, then Save. Opens only for the owner's Google login (no password UI, no token deep-links). noindex.vercel.json — 60s maxDuration for the dashboard/sports functions, 15s for admin, a /admin → /admin.html rewrite, and the daily crons that warm the cache.deliver-remarkable.ymldeliver-special.ymlMERIDIAN_REPOMERIDIAN_BRANCHmarkt1600/dailymagmainVAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY | push.js, notify.js | Web Push signing keypair (npx web-push generate-vapid-keys). The public key goes to the browser; the private key signs every send — without it nobody can push to your devices. |
CRON_SECRET | notify.js | Recommended. Vercel sends it as a Bearer header on cron invocations; when set, manual /api/notify hits need ?token=<ADMIN_SECRET> instead. |
GOOGLE_CLIENT_ID | login.js | OAuth client ID (Web application) from Google Cloud Console with https://marktan.ai as an authorized JavaScript origin. Enables the footer's Google Sign-In owner login. |
MERIDIAN_SPECIALS_KEY | special.js | Base64 PKCS8 DER X25519 private key that decrypts MERIDIAN's special editions. The matching public key is committed in the dailymag repo (state/specials-pubkey.b64); the same value also lives as a GitHub Actions secret on dailymag for the reMarkable delivery workflow. |
SESSION_SECRET | _session.js | Optional. Dedicated HMAC key for owner login sessions; defaults to ADMIN_SECRET, then DASHBOARD_SECRET. |
PRIVATE_STORE_KEY | private-events.js | Optional. Dedicated encryption key for the private calendar file; defaults to PUSH_STORE_KEY, then VAPID_PRIVATE_KEY. |
PUSH_STORE_KEY | _pushstore.js | Optional. Separate encryption key for the committed subscription file; defaults to VAPID_PRIVATE_KEY. |