Native Shell
Native Shell은 모든 플랫폼의 앱 안에서 만들어지는 AI UI입니다
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A collection of interactive visualizations and experiments built with SvelteKit and D3.js. This sandbox serves as a playground for exploring data visualization techniques, mathematical concepts, and interactive web experiences.
npm install
Development mode:
npm run dev
Production build:
npm run build
npm run preview
This will start a Vite development server on port 5173 (dev mode) or port 4173 (preview mode).
src/
├── routes/
│ ├── +layout.svelte # Bare root layout (just a slot)
│ ├── (sandbox)/ # Route group: sandbox pages share its layout
│ │ ├── +layout.svelte # Sandbox layout with navigation
│ │ ├── +page.svelte # Main listing page
│ │ ├── family-math/
│ │ │ ├── linear/+page.svelte # Linear growth visualization
│ │ │ ├── linear-embed/+page.svelte # Embed version
│ │ │ └── ... # quadratic, exponential, factorial (+ embeds)
│ │ └── swim-tracker/
│ │ ├── +page.svelte # Public demo (synthetic data)
│ │ └── [family]/+page.svelte # Gated family results page
│ ├── (dog-vote)/dog-vote/ # Route group with its own layout (no sandbox nav)
│ │ ├── +page.server.js # Redirects to the default dog
│ │ └── [dog]/+page.svelte # The guessing game
│ └── api/ # Server endpoints (swim data, dog votes)
└── lib/
├── components/
│ ├── FamilySlider.svelte # Shared slider component
│ ├── visualizations/ # Family math visualization components
│ ├── swim-tracker/ # Swim tracker components
│ └── dog-vote/ # Breed-guessing game components
├── server/ # Server-only code (swim gate, dog-vote Sheets store)
└── utils/ # Data processing utilities
Routes: /family-math/linear | /family-math/linear-embed
An interactive visualization demonstrating linear growth patterns through cost calculations.
Routes: /family-math/quadratic | /family-math/quadratic-embed
An interactive visualization showing how relationships grow quadratically as group size increases.
Routes: /family-math/exponential | /family-math/exponential-embed
An interactive visualization demonstrating how decision-making complexity grows exponentially.
Routes: /family-math/factorial | /family-math/factorial-embed
An interactive visualization showing how arrangement complexity grows factorially.
Routes: /swim-tracker (public demo) | /swim-tracker/family (gated, real data)
A swim meet tracker with a public demo and a password-protected family results page.
src/lib/data/demoSwimData.js — no network calls, no password needed/api/swim-data (a Vercel serverless function). Requires the correct SWIM_PASSWORD. Google Sheet CSV URLs (MEETS_CSV_URL, RACES_CSV_URL, SWIMMERS_CSV_URL) are kept in server-side env vars and are never shipped to the browser. See src/routes/swim-tracker/README.md and .env.example for setup instructions.Routes: /dog-vote (redirects to the default dog) | /dog-vote/<slug> (one game per dog)
A mobile-first game for guessing a mystery mutt's breed mix before a DNA test (e.g. Wisdom Panel) comes back. Visitors pick 1–5 breeds from the sheet's list (by searching or browsing a photo gallery) and percentages in steps of 5 that add up to 100, and only see the crowd's average and everyone's guesses after guessing. When the owner flips the reveal switch, the page shows the real breakdown with an animated reveal, a scored leaderboard and fun callouts.
breeds tab. Leaderboard ties go to whoever's counted guess came first.docs/superpowers/specs/2026-10-23-dog-vote-design.mdCreate a Google service account (one-time; it can serve every dog):
Create the dog's Google Sheet with these four tabs. Headers go in row 1 and are matched case-insensitively.
settings: key/value rows
| key | value |
|---|---|
| dog_name | Biscuit |
| pronoun | he / she / they |
| intro | Optional text shown on the landing page |
| photos | 1.jpg, 2.jpg (files in static/dog-vote/<slug>/, or full https:// URLs; the first is the hero) |
votes: headers timestamp | name | guesses | comment. The app appends rows and never edits them. Each name's latest row counts, matched case-insensitively.
breeds: headers breed | group | image_url (image_url is optional). Paste docs/dog-vote/breeds-seed.csv (~70 common breeds) to start. The groups follow Wisdom Panel's: Asian and Oceanian, Companion, Guard, Herding, Hound, Middle Eastern and African, Mountain Dogs, Sighthound, Sporting, Street Dogs, Terrier, Wild Canids. The seed list's breed-to-group assignments are best guesses, so edit them freely.
results: a fixed layout, with nothing shown until B1 is TRUE:
| A | B | |
|---|---|---|
| 1 | revealed | FALSE |
| 2 | breed_or_group | pct |
| 3+ | e.g. Beagle | e.g. 37.5 |
Share the sheet with the service account's email (…@….iam.gserviceaccount.com) as Editor.
Set env vars in for local use, and in Vercel project settings for production (see ):
In npm run dev, setup problems show a message naming exactly what's wrong (missing env var, missing tab or header, sheet not shared). In production, visitors only see "This game isn't set up yet."
DOGVOTE_<SLUG>_SHEET_ID (e.g. DOGVOTE_BISCUIT_SHEET_ID).static/dog-vote/<slug>/ and list them in its settings tab. Its page is /dog-vote/<slug>.Fill in results rows 3 and below with the DNA breakdown (breeds or groups, as on the report), then set B1 to TRUE. Within about 15 seconds everyone sees the reveal and voting closes.
All visualizations have dedicated embed routes (*-embed) optimized for iframe embedding:
For a single iframe:
<iframe id="linear-viz"
src="https://yourdomain.com/family-math/linear-embed"
width="100%"
style="border: none;">
</iframe>
<script>
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/iframe-resizer@4/js/iframeResizer.min.js';
script.onload = function() {
iFrameResize({ log: false }, '#linear-viz');
};
document.head.appendChild(script);
</script>
When embedding multiple visualizations on the same page, load the script once:
<!-- Your iframes -->
<iframe id="linear-viz" src="https://yourdomain.com/family-math/linear-embed" width="100%" style="border: none;"></iframe>
<iframe id="quadratic-viz" src="https://yourdomain.com/family-math/quadratic-embed" width="100%" style="border: none;"></iframe>
<iframe id="exponential-viz" src="https://yourdomain.com/family-math/exponential-embed" width="100%" style="border: none;"></iframe>
<iframe id="factorial-viz" src="https://yourdomain.com/family-math/factorial-embed" width="100%" style="border: none;"></iframe>
<!-- Load iframe-resizer once for all iframes -->
<script>
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/iframe-resizer@4/js/iframeResizer.min.js';
script.onload = function() {
iFrameResize({ log: false }, '#linear-viz');
iFrameResize({ log: false }, '#quadratic-viz');
iFrameResize({ log: false }, '#exponential-viz');
iFrameResize({ log: false }, '#factorial-viz');
};
document.head.appendChild(script);
</script>
Note: The embed pages automatically include the iframe-resizer child component, so you only need to set up the parent side.
src/lib/components/visualizations/src/routes/your-experiment/+page.sveltesrc/routes/your-experiment-embed/+page.sveltesrc/routes/+page.svelte)/api/swim-data runs as a serverless functionnpm run build
npm run deploy
Configured for Vercel deployment with proper headers for iframe embedding.
This is a personal sandbox project, but feel free to fork and create your own experiments!
ISC
.env.env.exampleGOOGLE_SERVICE_ACCOUNT_EMAIL: the JSON key's client_emailGOOGLE_PRIVATE_KEY: the JSON key's private_key, with its \n sequences kept, in double quotesDOGVOTE_<SLUG>_SHEET_ID: the id between /d/ and /edit in the sheet URLDOGVOTE_DEFAULT_SLUG: where /dog-vote redirectsAdd photos to static/dog-vote/<slug>/. This repo is public, so resize each photo and strip its metadata first: phone photos carry GPS coordinates. On macOS, re-encoding through ImageIO drops all metadata, for example with a small Swift script that uses CGImageSourceCreateThumbnailAtIndex (max 1600px) and CGImageDestinationAddImage with no properties. Check the file bytes (strings photo.jpg | grep -i gps), not Spotlight, which caches old metadata.