@chuzi/shared 0.2.0
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/LICENSE +21 -0
- package/README.md +52 -0
- package/dist/api/index.d.ts +122 -0
- package/dist/api/index.js +108 -0
- package/dist/api/index.js.map +1 -0
- package/dist/config/index.d.ts +39 -0
- package/dist/config/index.js +404 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +627 -0
- package/dist/index.js.map +1 -0
- package/dist/input/index.d.ts +70 -0
- package/dist/input/index.js +41 -0
- package/dist/input/index.js.map +1 -0
- package/dist/realms/cosmos/components/index.d.ts +68 -0
- package/dist/realms/cosmos/components/index.js +172 -0
- package/dist/realms/cosmos/components/index.js.map +1 -0
- package/dist/realms/cosmos/index.d.ts +8 -0
- package/dist/realms/cosmos/index.js +76 -0
- package/dist/realms/cosmos/index.js.map +1 -0
- package/dist/realms/index.d.ts +109 -0
- package/dist/realms/index.js +23 -0
- package/dist/realms/index.js.map +1 -0
- package/dist/realms/wilds/components/index.d.ts +88 -0
- package/dist/realms/wilds/components/index.js +359 -0
- package/dist/realms/wilds/components/index.js.map +1 -0
- package/dist/realms/wilds/index.d.ts +8 -0
- package/dist/realms/wilds/index.js +70 -0
- package/dist/realms/wilds/index.js.map +1 -0
- package/dist/themes/index.d.ts +46 -0
- package/dist/themes/index.js +63 -0
- package/dist/themes/index.js.map +1 -0
- package/dist/types/index.d.ts +292 -0
- package/dist/types/index.js +3 -0
- package/dist/types/index.js.map +1 -0
- package/dist/ui/index.d.ts +71 -0
- package/dist/ui/index.js +551 -0
- package/dist/ui/index.js.map +1 -0
- package/package.json +107 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/realms/wilds/components/Tree.tsx","../../../../src/realms/wilds/components/ForestBackdrop.tsx","../../../../src/realms/wilds/components/WildsWorld.tsx","../../../../src/realms/wilds/index.ts","../../../../src/realms/wilds/components/layout.ts","../../../../src/realms/wilds/components/WildsSandbox.tsx"],"names":["useRef","useMemo","useFrame","jsxs","jsx","mulberry32"],"mappings":"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","file":"index.js","sourcesContent":["import { useRef, useMemo } from \"react\";\nimport { useFrame } from \"@react-three/fiber\";\nimport type { Group } from \"three\";\nimport type { AtomVisualProps } from \"../../index.js\";\n\nexport interface TreeProps {\n visual: AtomVisualProps;\n onSelect?: () => void;\n}\n\n/**\n * A single film-tree with a lush, multi-clustered canopy. Foliage is built\n * from overlapping dodecahedrons arranged around the crown — reads as a\n * dense, heavily-branched tree. Trees within a genre clump share the same\n * hue; brightness scales with popularity.\n */\nexport function Tree({ visual, onSelect }: TreeProps) {\n const ref = useRef<Group>(null);\n\n useFrame(({ clock }) => {\n if (!ref.current) return;\n const phase = visual.position[0] * 0.4 + visual.position[2] * 0.6;\n const sway = Math.sin(clock.elapsedTime * 0.6 + phase) * 0.04;\n ref.current.rotation.z = sway;\n });\n\n const trunkHeight = 1.6 + visual.scale * 2.4;\n const trunkRadius = 0.09 + visual.scale * 0.055;\n const lightness = 52 + visual.intensity * 18;\n const canopyColor = `hsl(${visual.hue}, 82%, ${lightness}%)`;\n const trunkColor = \"#6b5a45\";\n\n const seed = Math.abs(Math.round(visual.position[0] * 127 + visual.position[2] * 311));\n\n const foliage = useMemo(() => {\n const clusters: { x: number; y: number; z: number; r: number }[] = [];\n const crownY = trunkHeight * 0.78;\n const baseR = 0.65 + visual.scale * 0.5 + visual.intensity * 0.3;\n\n clusters.push({ x: 0, y: crownY + baseR * 0.35, z: 0, r: baseR });\n clusters.push({ x: 0, y: crownY + baseR * 0.95, z: 0, r: baseR * 0.55 });\n\n const mainCount = 5 + Math.floor(visual.scale * 3);\n for (let i = 0; i < mainCount; i++) {\n const a = (i / mainCount) * Math.PI * 2 + (seed % 100) * 0.063;\n const spread = baseR * (0.6 + ((seed + i * 7) % 5) * 0.09);\n const yOff = ((seed + i * 13) % 7 - 3) * 0.1;\n const sz = baseR * (0.38 + ((seed + i * 11) % 5) * 0.07);\n clusters.push({\n x: Math.cos(a) * spread,\n y: crownY + yOff,\n z: Math.sin(a) * spread,\n r: sz,\n });\n }\n\n const lowerCount = 3 + Math.floor(visual.scale * 2);\n for (let i = 0; i < lowerCount; i++) {\n const a = (i / lowerCount) * Math.PI * 2 + (seed % 50) * 0.126;\n const spread = baseR * 0.85 + 0.25;\n clusters.push({\n x: Math.cos(a) * spread,\n y: crownY - 0.35 - ((seed + i * 17) % 4) * 0.12,\n z: Math.sin(a) * spread,\n r: baseR * (0.28 + ((seed + i * 7) % 3) * 0.06),\n });\n }\n\n return clusters;\n }, [trunkHeight, visual.scale, visual.intensity, seed]);\n\n function handleClick(e: { stopPropagation: () => void }) {\n if (!onSelect) return;\n e.stopPropagation();\n onSelect();\n }\n\n const onClick = onSelect ? handleClick : undefined;\n\n return (\n <group ref={ref} position={visual.position}>\n <mesh position={[0, trunkHeight / 2, 0]} onClick={onClick}>\n <cylinderGeometry args={[trunkRadius * 0.65, trunkRadius, trunkHeight, 8]} />\n <meshStandardMaterial color={trunkColor} roughness={0.9} />\n </mesh>\n {foliage.map((c, i) => (\n <mesh key={i} position={[c.x, c.y, c.z]} onClick={onClick}>\n <dodecahedronGeometry args={[c.r, 1]} />\n <meshStandardMaterial color={canopyColor} roughness={0.7} />\n </mesh>\n ))}\n </group>\n );\n}\n","import { useMemo, useRef } from \"react\";\nimport { useFrame } from \"@react-three/fiber\";\nimport type { InstancedMesh } from \"three\";\nimport { Object3D, Color } from \"three\";\n\nexport interface ForestBackdropProps {\n /** Number of ambient backdrop trees. Default 320. */\n count?: number;\n /** Inner radius — backdrop starts beyond this. */\n innerRadius?: number;\n /** Outer radius — backdrop fades out by here. */\n outerRadius?: number;\n /** Deterministic seed; identical seeds produce identical forests. */\n seed?: number;\n}\n\n/**\n * Ambient surrounding forest. Three overlapping canopy layers per tree\n * (dodecahedrons at staggered offsets) give the backdrop lush, full\n * silhouettes. Four instanced draw calls total (trunk + 3 canopy layers)\n * keep the cost constant regardless of count.\n */\nexport function ForestBackdrop({\n count = 320,\n innerRadius = 36,\n outerRadius = 78,\n seed = 7,\n}: ForestBackdropProps) {\n const trunkRef = useRef<InstancedMesh>(null);\n const canopy1Ref = useRef<InstancedMesh>(null);\n const canopy2Ref = useRef<InstancedMesh>(null);\n const canopy3Ref = useRef<InstancedMesh>(null);\n\n const placements = useMemo(\n () => buildPlacements(count, innerRadius, outerRadius, seed),\n [count, innerRadius, outerRadius, seed],\n );\n\n useFrame(() => {\n const trunk = trunkRef.current;\n const c1 = canopy1Ref.current;\n const c2 = canopy2Ref.current;\n const c3 = canopy3Ref.current;\n if (!trunk || !c1 || !c2 || !c3) return;\n if (trunk.userData.placed) return;\n\n const dummy = new Object3D();\n const color = new Color();\n\n placements.forEach((p, i) => {\n const trunkH = p.trunkHeight;\n const canopyH = p.canopyHeight;\n const canopyR = p.canopyRadius;\n\n dummy.position.set(p.x, trunkH / 2, p.z);\n dummy.rotation.set(0, p.rot, 0);\n dummy.scale.set(p.trunkRadius * 2, trunkH, p.trunkRadius * 2);\n dummy.updateMatrix();\n trunk.setMatrixAt(i, dummy.matrix);\n\n dummy.position.set(p.x, trunkH + canopyH * 0.3, p.z);\n dummy.rotation.set(0, p.rot, 0);\n dummy.scale.set(canopyR * 0.9, canopyH * 0.5, canopyR * 0.9);\n dummy.updateMatrix();\n c1.setMatrixAt(i, dummy.matrix);\n\n const off2x = Math.cos(p.rot + 0.8) * canopyR * 0.35;\n const off2z = Math.sin(p.rot + 0.8) * canopyR * 0.35;\n dummy.position.set(p.x + off2x, trunkH + canopyH * 0.5, p.z + off2z);\n dummy.rotation.set(0, p.rot * 1.3, 0);\n dummy.scale.set(canopyR * 0.7, canopyH * 0.4, canopyR * 0.7);\n dummy.updateMatrix();\n c2.setMatrixAt(i, dummy.matrix);\n\n const off3x = Math.cos(p.rot + 3.2) * canopyR * 0.4;\n const off3z = Math.sin(p.rot + 3.2) * canopyR * 0.4;\n dummy.position.set(p.x + off3x, trunkH + canopyH * 0.1, p.z + off3z);\n dummy.rotation.set(0, p.rot * 0.7, 0);\n dummy.scale.set(canopyR * 0.55, canopyH * 0.35, canopyR * 0.55);\n dummy.updateMatrix();\n c3.setMatrixAt(i, dummy.matrix);\n\n const hue = BACKDROP_HUES[i % BACKDROP_HUES.length];\n color.setHSL(hue / 360, 0.5, 0.36);\n c1.setColorAt(i, color);\n color.setHSL(hue / 360, 0.5, 0.4);\n c2.setColorAt(i, color);\n color.setHSL(hue / 360, 0.5, 0.32);\n c3.setColorAt(i, color);\n });\n\n trunk.instanceMatrix.needsUpdate = true;\n c1.instanceMatrix.needsUpdate = true;\n c2.instanceMatrix.needsUpdate = true;\n c3.instanceMatrix.needsUpdate = true;\n if (c1.instanceColor) c1.instanceColor.needsUpdate = true;\n if (c2.instanceColor) c2.instanceColor.needsUpdate = true;\n if (c3.instanceColor) c3.instanceColor.needsUpdate = true;\n trunk.userData.placed = true;\n });\n\n return (\n <group>\n <instancedMesh ref={trunkRef} args={[undefined, undefined, count]}>\n <cylinderGeometry args={[1, 1, 1, 6]} />\n <meshStandardMaterial color=\"#5a4a38\" roughness={0.95} />\n </instancedMesh>\n <instancedMesh ref={canopy1Ref} args={[undefined, undefined, count]}>\n <dodecahedronGeometry args={[1, 1]} />\n <meshStandardMaterial color=\"#ffffff\" roughness={0.8} />\n </instancedMesh>\n <instancedMesh ref={canopy2Ref} args={[undefined, undefined, count]}>\n <dodecahedronGeometry args={[1, 1]} />\n <meshStandardMaterial color=\"#ffffff\" roughness={0.8} />\n </instancedMesh>\n <instancedMesh ref={canopy3Ref} args={[undefined, undefined, count]}>\n <dodecahedronGeometry args={[1, 1]} />\n <meshStandardMaterial color=\"#ffffff\" roughness={0.8} />\n </instancedMesh>\n </group>\n );\n}\n\nconst BACKDROP_HUES = [120, 140, 100, 160, 80, 150, 95, 130, 110, 170];\n\ninterface Placement {\n x: number;\n z: number;\n rot: number;\n trunkHeight: number;\n trunkRadius: number;\n canopyHeight: number;\n canopyRadius: number;\n}\n\nfunction buildPlacements(\n count: number,\n innerRadius: number,\n outerRadius: number,\n seed: number,\n): Placement[] {\n const random = mulberry32(seed);\n const out: Placement[] = [];\n for (let i = 0; i < count; i++) {\n const t = Math.sqrt(random());\n const r = innerRadius + t * (outerRadius - innerRadius);\n const theta = random() * Math.PI * 2;\n const x = Math.cos(theta) * r;\n const z = Math.sin(theta) * r;\n\n const sizeJitter = 0.7 + random() * 0.9;\n const trunkHeight = 1.6 * sizeJitter;\n const trunkRadius = 0.18 * sizeJitter;\n const canopyHeight = 2.4 * sizeJitter;\n const canopyRadius = 1.1 * sizeJitter;\n\n out.push({\n x,\n z,\n rot: random() * Math.PI * 2,\n trunkHeight,\n trunkRadius,\n canopyHeight,\n canopyRadius,\n });\n }\n return out;\n}\n\nfunction mulberry32(seed: number): () => number {\n let s = seed >>> 0;\n return () => {\n s = (s + 0x6d2b79f5) >>> 0;\n let t = s;\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n","import { Canvas } from \"@react-three/fiber\";\nimport { OrbitControls, Stars } from \"@react-three/drei\";\nimport type { ReactNode } from \"react\";\nimport { ForestBackdrop } from \"./ForestBackdrop.js\";\n\nconst SKY = \"#0e1030\";\nconst GROUND_COLOR = \"#2a5a35\";\n\nexport interface WildsWorldProps {\n children: ReactNode;\n /** Pixel device ratio cap. Default [1,2] — keeps perf bounded on retina laptops. */\n dpr?: number | [number, number];\n}\n\n/**\n * Wilds environment shell. A lush forest under a cosmic sky — the stars\n * visible overhead are the same cosmos the director may have just left.\n * Bright hemisphere + directional lighting keeps the canopy vivid even\n * against the dark backdrop.\n */\nexport function WildsWorld({ children, dpr = [1, 2] }: WildsWorldProps) {\n return (\n <Canvas\n camera={{ position: [0, 8, 36], fov: 60, near: 0.1, far: 500 }}\n dpr={dpr}\n gl={{ antialias: true }}\n >\n <color attach=\"background\" args={[SKY]} />\n <fog attach=\"fog\" args={[SKY, 70, 180]} />\n <Stars\n radius={180}\n depth={80}\n count={2500}\n factor={4}\n saturation={0.5}\n fade\n speed={0.8}\n />\n <ambientLight intensity={0.65} />\n <hemisphereLight args={[\"#f0f8ff\", \"#3a5a38\", 1.2]} />\n <directionalLight position={[10, 30, 8]} intensity={1.5} color=\"#fff5e0\" />\n <Ground />\n <ForestBackdrop />\n <OrbitControls\n enablePan={false}\n maxDistance={80}\n minDistance={6}\n maxPolarAngle={Math.PI / 2.05}\n />\n {children}\n </Canvas>\n );\n}\n\nfunction Ground() {\n return (\n <mesh rotation={[-Math.PI / 2, 0, 0]} position={[0, -0.01, 0]} receiveShadow>\n <circleGeometry args={[120, 64]} />\n <meshStandardMaterial color={GROUND_COLOR} roughness={0.9} />\n </mesh>\n );\n}\n","import type { StoryListItem } from \"../../types/index.js\";\nimport type { AtomMapping, AtomState, AudioPalette, MotionTokens } from \"../index.js\";\n\n/**\n * WILDS realm — pure-data layer. Mirrors `cosmos/index.ts` shape but with\n * forest semantics: films are trees, runtime → height, popularity → canopy\n * density, genre → species, mood → foliage color.\n *\n * Mapping rationale:\n * runtime → scale (longer film = taller tree)\n * popularity → intensity (more watches = lusher canopy)\n * genre → hue (species: oak=drama yellow, pine=thriller cool\n * green, willow=romance pink-green, dead/gnarled\n * =horror umber)\n * state → marker post next to trunk (handled by Atom component).\n */\n\nconst GENRE_HUE: Record<string, number> = {\n drama: 70, // oak — warm green-gold\n thriller: 150, // pine — cool green\n horror: 25, // dead/gnarled — burnt umber\n comedy: 95, // birch — bright spring\n romance: 330, // cherry blossom — pink\n scifi: 180, // alien luminescent\n documentary: 110, // generic forest green\n animation: 280, // fantasy violet\n};\n\nfunction clamp01(n: number): number {\n return Math.max(0, Math.min(1, n));\n}\n\nfunction popularityToIntensity(film: StoryListItem): number {\n const watches = Math.max(0, film.watch_starts_count);\n const log = Math.log10(1 + watches);\n return clamp01(log / 6);\n}\n\nfunction deriveScale(film: StoryListItem): number {\n // Trees are noticeably more height-variable than stars are size-variable;\n // map to a wider band than cosmos uses.\n const scenes = film.scenes_count ?? 1;\n return clamp01(0.3 + Math.log10(1 + scenes) / 3);\n}\n\nfunction deriveHue(film: StoryListItem): number {\n const genreKey = (film.genre ?? \"\").toLowerCase().replace(/[^a-z]/g, \"\");\n const hue = GENRE_HUE[genreKey];\n return hue !== undefined ? hue : 110;\n}\n\nfunction deriveState(film: StoryListItem): AtomState {\n return film.published ? \"default\" : \"new\";\n}\n\nexport const wildsMapping: AtomMapping = (film) => ({\n position: [0, 0, 0], // assigned by the realm's spatial layouter\n scale: deriveScale(film),\n hue: deriveHue(film),\n intensity: popularityToIntensity(film),\n state: deriveState(film),\n metadata: {\n title: film.title,\n popularity: film.watch_starts_count,\n genre: film.genre,\n },\n});\n\nexport const wildsMotion: MotionTokens = {\n // Walking is slower and more grounded than flying through space.\n flightAcceleration: 8,\n flightDamping: 0.86,\n focusEaseMs: 480,\n engageDurationMs: 1100,\n backDurationMs: 1100,\n};\n\nexport const wildsAudio: AudioPalette = {\n ambientLoop: \"audio/wilds/ambient-forest.ogg\",\n focusChime: \"audio/wilds/leaf-rustle.ogg\",\n engageImpact: \"audio/wilds/bark-open.ogg\",\n backWhoosh: \"audio/wilds/bark-close.ogg\",\n};\n","/**\n * Spatial distribution helpers for the wilds realm. Trees grow in clumps\n * (groves), not on a uniform grid: pick a small set of cluster anchors,\n * then scatter trees around them with a soft falloff. Deterministic when a\n * seed is provided so the same catalog produces the same forest.\n */\n\nexport type Vec3 = [number, number, number];\n\nexport interface DistributeForestOptions {\n /** Outer radius the forest occupies, in world units. */\n radius?: number;\n /** Number of clumps. Capped at `count`. */\n clumpCount?: number;\n /** Spread of each clump (stddev-ish, in world units). */\n clumpSpread?: number;\n /** Deterministic seed; identical seeds produce identical layouts. */\n seed?: number;\n}\n\n/**\n * Cluster trees around a small number of anchor points, with each anchor\n * placed in a disk of `radius`. Each tree is offset from its anchor by a\n * 2D gaussian-ish jitter (`clumpSpread`). Y is always 0 — trees stand on\n * the ground plane.\n */\nexport function distributeForest(\n count: number,\n options: DistributeForestOptions = {},\n): Vec3[] {\n const radius = options.radius ?? 28;\n const clumpSpread = options.clumpSpread ?? 4;\n const random = options.seed !== undefined ? mulberry32(options.seed) : Math.random;\n\n const desiredClumps = options.clumpCount ?? Math.max(2, Math.round(count / 4));\n const clumpCount = Math.max(1, Math.min(count, desiredClumps));\n\n const anchors: Vec3[] = [];\n for (let i = 0; i < clumpCount; i++) {\n const r = Math.sqrt(random()) * radius;\n const theta = random() * Math.PI * 2;\n anchors.push([Math.cos(theta) * r, 0, Math.sin(theta) * r]);\n }\n\n const positions: Vec3[] = [];\n for (let i = 0; i < count; i++) {\n const anchor = anchors[i % clumpCount];\n const dx = gaussian(random) * clumpSpread;\n const dz = gaussian(random) * clumpSpread;\n positions.push([anchor[0] + dx, 0, anchor[2] + dz]);\n }\n return positions;\n}\n\nfunction gaussian(random: () => number): number {\n // Box–Muller. Two uniforms in, one ~N(0,1) out.\n const u1 = Math.max(1e-9, random());\n const u2 = random();\n return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);\n}\n\nfunction mulberry32(seed: number): () => number {\n let s = seed >>> 0;\n return () => {\n s = (s + 0x6d2b79f5) >>> 0;\n let t = s;\n t = Math.imul(t ^ (t >>> 15), t | 1);\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61);\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n","import { useMemo } from \"react\";\nimport type { StoryListItem } from \"../../../types/index.js\";\nimport { wildsMapping } from \"../index.js\";\nimport { Tree } from \"./Tree.js\";\nimport { WildsWorld } from \"./WildsWorld.js\";\nimport { distributeForest, type Vec3 } from \"./layout.js\";\n\nexport interface WildsSandboxProps {\n films: StoryListItem[];\n onFilmSelect?: (film: StoryListItem) => void;\n /** Layout seed — same seed + same films = same forest. */\n seed?: number;\n}\n\n/**\n * Drop-in 3D wilds sandbox: hand a list of films, get back a navigable\n * forest where each film is a tree. Trees are clustered into clumps\n * (groves) rather than uniformly distributed — mirrors how real forests\n * grow, and reads better visually than a tree grid. Mirrors `CosmosSandbox`.\n */\nexport function WildsSandbox({\n films,\n onFilmSelect,\n seed = 1,\n}: WildsSandboxProps) {\n const placed = useMemo(() => {\n const positions: Vec3[] = distributeForest(films.length, { seed });\n return films.map((film, i) => ({\n film,\n visual: { ...wildsMapping(film), position: positions[i] },\n }));\n }, [films, seed]);\n\n return (\n <WildsWorld>\n {placed.map(({ film, visual }) => (\n <Tree\n key={film.id}\n visual={visual}\n onSelect={onFilmSelect ? () => onFilmSelect(film) : undefined}\n />\n ))}\n </WildsWorld>\n );\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AudioPalette, AtomMapping, MotionTokens } from '../index.js';
|
|
2
|
+
import '../../types/index.js';
|
|
3
|
+
|
|
4
|
+
declare const wildsMapping: AtomMapping;
|
|
5
|
+
declare const wildsMotion: MotionTokens;
|
|
6
|
+
declare const wildsAudio: AudioPalette;
|
|
7
|
+
|
|
8
|
+
export { wildsAudio, wildsMapping, wildsMotion };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
// src/realms/wilds/index.ts
|
|
2
|
+
var GENRE_HUE = {
|
|
3
|
+
drama: 70,
|
|
4
|
+
// oak — warm green-gold
|
|
5
|
+
thriller: 150,
|
|
6
|
+
// pine — cool green
|
|
7
|
+
horror: 25,
|
|
8
|
+
// dead/gnarled — burnt umber
|
|
9
|
+
comedy: 95,
|
|
10
|
+
// birch — bright spring
|
|
11
|
+
romance: 330,
|
|
12
|
+
// cherry blossom — pink
|
|
13
|
+
scifi: 180,
|
|
14
|
+
// alien luminescent
|
|
15
|
+
documentary: 110,
|
|
16
|
+
// generic forest green
|
|
17
|
+
animation: 280
|
|
18
|
+
// fantasy violet
|
|
19
|
+
};
|
|
20
|
+
function clamp01(n) {
|
|
21
|
+
return Math.max(0, Math.min(1, n));
|
|
22
|
+
}
|
|
23
|
+
function popularityToIntensity(film) {
|
|
24
|
+
const watches = Math.max(0, film.watch_starts_count);
|
|
25
|
+
const log = Math.log10(1 + watches);
|
|
26
|
+
return clamp01(log / 6);
|
|
27
|
+
}
|
|
28
|
+
function deriveScale(film) {
|
|
29
|
+
const scenes = film.scenes_count ?? 1;
|
|
30
|
+
return clamp01(0.3 + Math.log10(1 + scenes) / 3);
|
|
31
|
+
}
|
|
32
|
+
function deriveHue(film) {
|
|
33
|
+
const genreKey = (film.genre ?? "").toLowerCase().replace(/[^a-z]/g, "");
|
|
34
|
+
const hue = GENRE_HUE[genreKey];
|
|
35
|
+
return hue !== void 0 ? hue : 110;
|
|
36
|
+
}
|
|
37
|
+
function deriveState(film) {
|
|
38
|
+
return film.published ? "default" : "new";
|
|
39
|
+
}
|
|
40
|
+
var wildsMapping = (film) => ({
|
|
41
|
+
position: [0, 0, 0],
|
|
42
|
+
// assigned by the realm's spatial layouter
|
|
43
|
+
scale: deriveScale(film),
|
|
44
|
+
hue: deriveHue(film),
|
|
45
|
+
intensity: popularityToIntensity(film),
|
|
46
|
+
state: deriveState(film),
|
|
47
|
+
metadata: {
|
|
48
|
+
title: film.title,
|
|
49
|
+
popularity: film.watch_starts_count,
|
|
50
|
+
genre: film.genre
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
var wildsMotion = {
|
|
54
|
+
// Walking is slower and more grounded than flying through space.
|
|
55
|
+
flightAcceleration: 8,
|
|
56
|
+
flightDamping: 0.86,
|
|
57
|
+
focusEaseMs: 480,
|
|
58
|
+
engageDurationMs: 1100,
|
|
59
|
+
backDurationMs: 1100
|
|
60
|
+
};
|
|
61
|
+
var wildsAudio = {
|
|
62
|
+
ambientLoop: "audio/wilds/ambient-forest.ogg",
|
|
63
|
+
focusChime: "audio/wilds/leaf-rustle.ogg",
|
|
64
|
+
engageImpact: "audio/wilds/bark-open.ogg",
|
|
65
|
+
backWhoosh: "audio/wilds/bark-close.ogg"
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export { wildsAudio, wildsMapping, wildsMotion };
|
|
69
|
+
//# sourceMappingURL=index.js.map
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/realms/wilds/index.ts"],"names":[],"mappings":";AAiBA,IAAM,SAAA,GAAoC;AAAA,EACxC,KAAA,EAAO,EAAA;AAAA;AAAA,EACP,QAAA,EAAU,GAAA;AAAA;AAAA,EACV,MAAA,EAAQ,EAAA;AAAA;AAAA,EACR,MAAA,EAAQ,EAAA;AAAA;AAAA,EACR,OAAA,EAAS,GAAA;AAAA;AAAA,EACT,KAAA,EAAO,GAAA;AAAA;AAAA,EACP,WAAA,EAAa,GAAA;AAAA;AAAA,EACb,SAAA,EAAW;AAAA;AACb,CAAA;AAEA,SAAS,QAAQ,CAAA,EAAmB;AAClC,EAAA,OAAO,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,GAAA,CAAI,CAAA,EAAG,CAAC,CAAC,CAAA;AACnC;AAEA,SAAS,sBAAsB,IAAA,EAA6B;AAC1D,EAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,KAAK,kBAAkB,CAAA;AACnD,EAAA,MAAM,GAAA,GAAM,IAAA,CAAK,KAAA,CAAM,CAAA,GAAI,OAAO,CAAA;AAClC,EAAA,OAAO,OAAA,CAAQ,MAAM,CAAC,CAAA;AACxB;AAEA,SAAS,YAAY,IAAA,EAA6B;AAGhD,EAAA,MAAM,MAAA,GAAS,KAAK,YAAA,IAAgB,CAAA;AACpC,EAAA,OAAO,QAAQ,GAAA,GAAM,IAAA,CAAK,MAAM,CAAA,GAAI,MAAM,IAAI,CAAC,CAAA;AACjD;AAEA,SAAS,UAAU,IAAA,EAA6B;AAC9C,EAAA,MAAM,QAAA,GAAA,CAAY,KAAK,KAAA,IAAS,EAAA,EAAI,aAAY,CAAE,OAAA,CAAQ,WAAW,EAAE,CAAA;AACvE,EAAA,MAAM,GAAA,GAAM,UAAU,QAAQ,CAAA;AAC9B,EAAA,OAAO,GAAA,KAAQ,SAAY,GAAA,GAAM,GAAA;AACnC;AAEA,SAAS,YAAY,IAAA,EAAgC;AACnD,EAAA,OAAO,IAAA,CAAK,YAAY,SAAA,GAAY,KAAA;AACtC;AAEO,IAAM,YAAA,GAA4B,CAAC,IAAA,MAAU;AAAA,EAClD,QAAA,EAAU,CAAC,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AAAA;AAAA,EAClB,KAAA,EAAO,YAAY,IAAI,CAAA;AAAA,EACvB,GAAA,EAAK,UAAU,IAAI,CAAA;AAAA,EACnB,SAAA,EAAW,sBAAsB,IAAI,CAAA;AAAA,EACrC,KAAA,EAAO,YAAY,IAAI,CAAA;AAAA,EACvB,QAAA,EAAU;AAAA,IACR,OAAO,IAAA,CAAK,KAAA;AAAA,IACZ,YAAY,IAAA,CAAK,kBAAA;AAAA,IACjB,OAAO,IAAA,CAAK;AAAA;AAEhB,CAAA;AAEO,IAAM,WAAA,GAA4B;AAAA;AAAA,EAEvC,kBAAA,EAAoB,CAAA;AAAA,EACpB,aAAA,EAAe,IAAA;AAAA,EACf,WAAA,EAAa,GAAA;AAAA,EACb,gBAAA,EAAkB,IAAA;AAAA,EAClB,cAAA,EAAgB;AAClB;AAEO,IAAM,UAAA,GAA2B;AAAA,EACtC,WAAA,EAAa,gCAAA;AAAA,EACb,UAAA,EAAY,6BAAA;AAAA,EACZ,YAAA,EAAc,2BAAA;AAAA,EACd,UAAA,EAAY;AACd","file":"index.js","sourcesContent":["import type { StoryListItem } from \"../../types/index.js\";\nimport type { AtomMapping, AtomState, AudioPalette, MotionTokens } from \"../index.js\";\n\n/**\n * WILDS realm — pure-data layer. Mirrors `cosmos/index.ts` shape but with\n * forest semantics: films are trees, runtime → height, popularity → canopy\n * density, genre → species, mood → foliage color.\n *\n * Mapping rationale:\n * runtime → scale (longer film = taller tree)\n * popularity → intensity (more watches = lusher canopy)\n * genre → hue (species: oak=drama yellow, pine=thriller cool\n * green, willow=romance pink-green, dead/gnarled\n * =horror umber)\n * state → marker post next to trunk (handled by Atom component).\n */\n\nconst GENRE_HUE: Record<string, number> = {\n drama: 70, // oak — warm green-gold\n thriller: 150, // pine — cool green\n horror: 25, // dead/gnarled — burnt umber\n comedy: 95, // birch — bright spring\n romance: 330, // cherry blossom — pink\n scifi: 180, // alien luminescent\n documentary: 110, // generic forest green\n animation: 280, // fantasy violet\n};\n\nfunction clamp01(n: number): number {\n return Math.max(0, Math.min(1, n));\n}\n\nfunction popularityToIntensity(film: StoryListItem): number {\n const watches = Math.max(0, film.watch_starts_count);\n const log = Math.log10(1 + watches);\n return clamp01(log / 6);\n}\n\nfunction deriveScale(film: StoryListItem): number {\n // Trees are noticeably more height-variable than stars are size-variable;\n // map to a wider band than cosmos uses.\n const scenes = film.scenes_count ?? 1;\n return clamp01(0.3 + Math.log10(1 + scenes) / 3);\n}\n\nfunction deriveHue(film: StoryListItem): number {\n const genreKey = (film.genre ?? \"\").toLowerCase().replace(/[^a-z]/g, \"\");\n const hue = GENRE_HUE[genreKey];\n return hue !== undefined ? hue : 110;\n}\n\nfunction deriveState(film: StoryListItem): AtomState {\n return film.published ? \"default\" : \"new\";\n}\n\nexport const wildsMapping: AtomMapping = (film) => ({\n position: [0, 0, 0], // assigned by the realm's spatial layouter\n scale: deriveScale(film),\n hue: deriveHue(film),\n intensity: popularityToIntensity(film),\n state: deriveState(film),\n metadata: {\n title: film.title,\n popularity: film.watch_starts_count,\n genre: film.genre,\n },\n});\n\nexport const wildsMotion: MotionTokens = {\n // Walking is slower and more grounded than flying through space.\n flightAcceleration: 8,\n flightDamping: 0.86,\n focusEaseMs: 480,\n engageDurationMs: 1100,\n backDurationMs: 1100,\n};\n\nexport const wildsAudio: AudioPalette = {\n ambientLoop: \"audio/wilds/ambient-forest.ogg\",\n focusChime: \"audio/wilds/leaf-rustle.ogg\",\n engageImpact: \"audio/wilds/bark-open.ogg\",\n backWhoosh: \"audio/wilds/bark-close.ogg\",\n};\n"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { RealmId } from '../types/index.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CSS custom property tokens, mirroring public/css/chuzi-realms.css.
|
|
5
|
+
* Use these for any non-DOM rendering (e.g. React Native, canvas).
|
|
6
|
+
*/
|
|
7
|
+
interface RealmThemeTokens {
|
|
8
|
+
bgDeep: string;
|
|
9
|
+
bgMid: string;
|
|
10
|
+
accent: string;
|
|
11
|
+
accentSoft: string;
|
|
12
|
+
text: string;
|
|
13
|
+
muted: string;
|
|
14
|
+
}
|
|
15
|
+
declare const THEME_TOKENS: Record<RealmId, RealmThemeTokens>;
|
|
16
|
+
/**
|
|
17
|
+
* Scene tree visualization theme, mirroring the THEMES object in
|
|
18
|
+
* resources/js/scene-tree-viewer.js.
|
|
19
|
+
*/
|
|
20
|
+
interface SceneTreeTheme {
|
|
21
|
+
bg: string;
|
|
22
|
+
edgeChoice: string;
|
|
23
|
+
edgeGoto: string;
|
|
24
|
+
nodeDefault: string;
|
|
25
|
+
nodeActive: string;
|
|
26
|
+
borderDefault: string;
|
|
27
|
+
borderActive: string;
|
|
28
|
+
labelDefault: string;
|
|
29
|
+
labelActive: string;
|
|
30
|
+
nodeLockedFill: string;
|
|
31
|
+
nodeLockedBorder: string;
|
|
32
|
+
labelLocked: string;
|
|
33
|
+
nodeShape: "star" | "rect";
|
|
34
|
+
rectRx: number;
|
|
35
|
+
}
|
|
36
|
+
declare const SCENE_TREE_THEMES: Record<RealmId, SceneTreeTheme>;
|
|
37
|
+
/**
|
|
38
|
+
* Get theme tokens for a realm, defaulting to wilds.
|
|
39
|
+
*/
|
|
40
|
+
declare function getThemeTokens(realmId: RealmId | null | undefined): RealmThemeTokens;
|
|
41
|
+
/**
|
|
42
|
+
* Get scene tree theme for a realm, defaulting to wilds.
|
|
43
|
+
*/
|
|
44
|
+
declare function getSceneTreeTheme(realmId: RealmId | null | undefined): SceneTreeTheme;
|
|
45
|
+
|
|
46
|
+
export { type RealmThemeTokens, SCENE_TREE_THEMES, type SceneTreeTheme, THEME_TOKENS, getSceneTreeTheme, getThemeTokens };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/themes/index.ts
|
|
2
|
+
var THEME_TOKENS = {
|
|
3
|
+
cosmos: {
|
|
4
|
+
bgDeep: "#04070d",
|
|
5
|
+
bgMid: "#0a1020",
|
|
6
|
+
accent: "#7eb8ff",
|
|
7
|
+
accentSoft: "rgba(126, 184, 255, 0.35)",
|
|
8
|
+
text: "#e8f0ff",
|
|
9
|
+
muted: "rgba(232, 240, 255, 0.65)"
|
|
10
|
+
},
|
|
11
|
+
wilds: {
|
|
12
|
+
bgDeep: "#0d120c",
|
|
13
|
+
bgMid: "#152018",
|
|
14
|
+
accent: "#7bc96f",
|
|
15
|
+
accentSoft: "rgba(123, 201, 111, 0.35)",
|
|
16
|
+
text: "#eef6ea",
|
|
17
|
+
muted: "rgba(238, 246, 234, 0.7)"
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
var SCENE_TREE_THEMES = {
|
|
21
|
+
cosmos: {
|
|
22
|
+
bg: "#020408",
|
|
23
|
+
edgeChoice: "#e8f0ff",
|
|
24
|
+
edgeGoto: "#4a9fff",
|
|
25
|
+
nodeDefault: "#ffffff",
|
|
26
|
+
nodeActive: "#ffd47e",
|
|
27
|
+
borderDefault: "#3a5080",
|
|
28
|
+
borderActive: "#fff6d0",
|
|
29
|
+
labelDefault: "rgba(220, 232, 255, 0.92)",
|
|
30
|
+
labelActive: "rgba(255, 246, 220, 0.98)",
|
|
31
|
+
nodeLockedFill: "#151a28",
|
|
32
|
+
nodeLockedBorder: "#2a3348",
|
|
33
|
+
labelLocked: "rgba(200, 210, 230, 0.35)",
|
|
34
|
+
nodeShape: "star",
|
|
35
|
+
rectRx: 2
|
|
36
|
+
},
|
|
37
|
+
wilds: {
|
|
38
|
+
bg: "#04070d",
|
|
39
|
+
edgeChoice: "#ffffff",
|
|
40
|
+
edgeGoto: "#6ecf7a",
|
|
41
|
+
nodeDefault: "#e8f5e4",
|
|
42
|
+
nodeActive: "#d31e2f",
|
|
43
|
+
borderDefault: "#2d4a32",
|
|
44
|
+
borderActive: "#ff9ea8",
|
|
45
|
+
labelDefault: "rgba(232, 245, 228, 0.92)",
|
|
46
|
+
labelActive: "rgba(255, 214, 219, 0.98)",
|
|
47
|
+
nodeLockedFill: "#1a221c",
|
|
48
|
+
nodeLockedBorder: "#2a3d30",
|
|
49
|
+
labelLocked: "rgba(200, 220, 200, 0.38)",
|
|
50
|
+
nodeShape: "rect",
|
|
51
|
+
rectRx: 3
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
function getThemeTokens(realmId) {
|
|
55
|
+
return THEME_TOKENS[realmId ?? "wilds"] ?? THEME_TOKENS.wilds;
|
|
56
|
+
}
|
|
57
|
+
function getSceneTreeTheme(realmId) {
|
|
58
|
+
return SCENE_TREE_THEMES[realmId ?? "wilds"] ?? SCENE_TREE_THEMES.wilds;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export { SCENE_TREE_THEMES, THEME_TOKENS, getSceneTreeTheme, getThemeTokens };
|
|
62
|
+
//# sourceMappingURL=index.js.map
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/themes/index.ts"],"names":[],"mappings":";AAeO,IAAM,YAAA,GAAkD;AAAA,EAC7D,MAAA,EAAQ;AAAA,IACN,MAAA,EAAQ,SAAA;AAAA,IACR,KAAA,EAAO,SAAA;AAAA,IACP,MAAA,EAAQ,SAAA;AAAA,IACR,UAAA,EAAY,2BAAA;AAAA,IACZ,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO;AAAA,GACT;AAAA,EACA,KAAA,EAAO;AAAA,IACL,MAAA,EAAQ,SAAA;AAAA,IACR,KAAA,EAAO,SAAA;AAAA,IACP,MAAA,EAAQ,SAAA;AAAA,IACR,UAAA,EAAY,2BAAA;AAAA,IACZ,IAAA,EAAM,SAAA;AAAA,IACN,KAAA,EAAO;AAAA;AAEX;AAuBO,IAAM,iBAAA,GAAqD;AAAA,EAChE,MAAA,EAAQ;AAAA,IACN,EAAA,EAAI,SAAA;AAAA,IACJ,UAAA,EAAY,SAAA;AAAA,IACZ,QAAA,EAAU,SAAA;AAAA,IACV,WAAA,EAAa,SAAA;AAAA,IACb,UAAA,EAAY,SAAA;AAAA,IACZ,aAAA,EAAe,SAAA;AAAA,IACf,YAAA,EAAc,SAAA;AAAA,IACd,YAAA,EAAc,2BAAA;AAAA,IACd,WAAA,EAAa,2BAAA;AAAA,IACb,cAAA,EAAgB,SAAA;AAAA,IAChB,gBAAA,EAAkB,SAAA;AAAA,IAClB,WAAA,EAAa,2BAAA;AAAA,IACb,SAAA,EAAW,MAAA;AAAA,IACX,MAAA,EAAQ;AAAA,GACV;AAAA,EACA,KAAA,EAAO;AAAA,IACL,EAAA,EAAI,SAAA;AAAA,IACJ,UAAA,EAAY,SAAA;AAAA,IACZ,QAAA,EAAU,SAAA;AAAA,IACV,WAAA,EAAa,SAAA;AAAA,IACb,UAAA,EAAY,SAAA;AAAA,IACZ,aAAA,EAAe,SAAA;AAAA,IACf,YAAA,EAAc,SAAA;AAAA,IACd,YAAA,EAAc,2BAAA;AAAA,IACd,WAAA,EAAa,2BAAA;AAAA,IACb,cAAA,EAAgB,SAAA;AAAA,IAChB,gBAAA,EAAkB,SAAA;AAAA,IAClB,WAAA,EAAa,2BAAA;AAAA,IACb,SAAA,EAAW,MAAA;AAAA,IACX,MAAA,EAAQ;AAAA;AAEZ;AAKO,SAAS,eAAe,OAAA,EAAuD;AACpF,EAAA,OAAO,YAAA,CAAa,OAAA,IAAW,OAAO,CAAA,IAAK,YAAA,CAAa,KAAA;AAC1D;AAKO,SAAS,kBAAkB,OAAA,EAAqD;AACrF,EAAA,OAAO,iBAAA,CAAkB,OAAA,IAAW,OAAO,CAAA,IAAK,iBAAA,CAAkB,KAAA;AACpE","file":"index.js","sourcesContent":["import type { RealmId } from \"../types/index.js\";\n\n/**\n * CSS custom property tokens, mirroring public/css/chuzi-realms.css.\n * Use these for any non-DOM rendering (e.g. React Native, canvas).\n */\nexport interface RealmThemeTokens {\n bgDeep: string;\n bgMid: string;\n accent: string;\n accentSoft: string;\n text: string;\n muted: string;\n}\n\nexport const THEME_TOKENS: Record<RealmId, RealmThemeTokens> = {\n cosmos: {\n bgDeep: \"#04070d\",\n bgMid: \"#0a1020\",\n accent: \"#7eb8ff\",\n accentSoft: \"rgba(126, 184, 255, 0.35)\",\n text: \"#e8f0ff\",\n muted: \"rgba(232, 240, 255, 0.65)\",\n },\n wilds: {\n bgDeep: \"#0d120c\",\n bgMid: \"#152018\",\n accent: \"#7bc96f\",\n accentSoft: \"rgba(123, 201, 111, 0.35)\",\n text: \"#eef6ea\",\n muted: \"rgba(238, 246, 234, 0.7)\",\n },\n};\n\n/**\n * Scene tree visualization theme, mirroring the THEMES object in\n * resources/js/scene-tree-viewer.js.\n */\nexport interface SceneTreeTheme {\n bg: string;\n edgeChoice: string;\n edgeGoto: string;\n nodeDefault: string;\n nodeActive: string;\n borderDefault: string;\n borderActive: string;\n labelDefault: string;\n labelActive: string;\n nodeLockedFill: string;\n nodeLockedBorder: string;\n labelLocked: string;\n nodeShape: \"star\" | \"rect\";\n rectRx: number;\n}\n\nexport const SCENE_TREE_THEMES: Record<RealmId, SceneTreeTheme> = {\n cosmos: {\n bg: \"#020408\",\n edgeChoice: \"#e8f0ff\",\n edgeGoto: \"#4a9fff\",\n nodeDefault: \"#ffffff\",\n nodeActive: \"#ffd47e\",\n borderDefault: \"#3a5080\",\n borderActive: \"#fff6d0\",\n labelDefault: \"rgba(220, 232, 255, 0.92)\",\n labelActive: \"rgba(255, 246, 220, 0.98)\",\n nodeLockedFill: \"#151a28\",\n nodeLockedBorder: \"#2a3348\",\n labelLocked: \"rgba(200, 210, 230, 0.35)\",\n nodeShape: \"star\",\n rectRx: 2,\n },\n wilds: {\n bg: \"#04070d\",\n edgeChoice: \"#ffffff\",\n edgeGoto: \"#6ecf7a\",\n nodeDefault: \"#e8f5e4\",\n nodeActive: \"#d31e2f\",\n borderDefault: \"#2d4a32\",\n borderActive: \"#ff9ea8\",\n labelDefault: \"rgba(232, 245, 228, 0.92)\",\n labelActive: \"rgba(255, 214, 219, 0.98)\",\n nodeLockedFill: \"#1a221c\",\n nodeLockedBorder: \"#2a3d30\",\n labelLocked: \"rgba(200, 220, 200, 0.38)\",\n nodeShape: \"rect\",\n rectRx: 3,\n },\n};\n\n/**\n * Get theme tokens for a realm, defaulting to wilds.\n */\nexport function getThemeTokens(realmId: RealmId | null | undefined): RealmThemeTokens {\n return THEME_TOKENS[realmId ?? \"wilds\"] ?? THEME_TOKENS.wilds;\n}\n\n/**\n * Get scene tree theme for a realm, defaulting to wilds.\n */\nexport function getSceneTreeTheme(realmId: RealmId | null | undefined): SceneTreeTheme {\n return SCENE_TREE_THEMES[realmId ?? \"wilds\"] ?? SCENE_TREE_THEMES.wilds;\n}\n"]}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
interface LoginRequest {
|
|
2
|
+
email: string;
|
|
3
|
+
password: string;
|
|
4
|
+
device_name: string;
|
|
5
|
+
}
|
|
6
|
+
interface LoginResponse {
|
|
7
|
+
token: string;
|
|
8
|
+
user: UserProfile;
|
|
9
|
+
}
|
|
10
|
+
interface UserProfile {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
email: string;
|
|
14
|
+
realm: RealmId | null;
|
|
15
|
+
needs_realm_choice: boolean;
|
|
16
|
+
locale: LocaleId | null;
|
|
17
|
+
avatar_url: string | null;
|
|
18
|
+
is_admin: boolean;
|
|
19
|
+
created_at: string;
|
|
20
|
+
}
|
|
21
|
+
interface UpdateRealmRequest {
|
|
22
|
+
realm: RealmId;
|
|
23
|
+
}
|
|
24
|
+
interface UpdateRealmResponse {
|
|
25
|
+
realm: RealmId;
|
|
26
|
+
user: UserProfile;
|
|
27
|
+
}
|
|
28
|
+
interface UpdateProfileRequest {
|
|
29
|
+
name?: string;
|
|
30
|
+
}
|
|
31
|
+
interface UpdateProfileResponse {
|
|
32
|
+
user: UserProfile;
|
|
33
|
+
}
|
|
34
|
+
interface StoryListItem {
|
|
35
|
+
id: string;
|
|
36
|
+
title: string;
|
|
37
|
+
description: string | null;
|
|
38
|
+
genre: string | null;
|
|
39
|
+
content_rating: ContentRating | null;
|
|
40
|
+
published: boolean;
|
|
41
|
+
published_version: number;
|
|
42
|
+
watch_starts_count: number;
|
|
43
|
+
choice_clicks_count: number;
|
|
44
|
+
scenes_count: number;
|
|
45
|
+
choices_count: number;
|
|
46
|
+
creator: {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
} | null;
|
|
50
|
+
created_at: string;
|
|
51
|
+
updated_at: string;
|
|
52
|
+
}
|
|
53
|
+
interface StoryPreview {
|
|
54
|
+
source: "trailer" | "title_scene" | "none";
|
|
55
|
+
title: string;
|
|
56
|
+
preview_url: string | null;
|
|
57
|
+
media_type: string | null;
|
|
58
|
+
is_ready: boolean;
|
|
59
|
+
}
|
|
60
|
+
interface PopularChoice {
|
|
61
|
+
label: string;
|
|
62
|
+
click_count: number;
|
|
63
|
+
}
|
|
64
|
+
interface StoryProgress {
|
|
65
|
+
last_scene_id: string | null;
|
|
66
|
+
bookmark_code: string | null;
|
|
67
|
+
playback_seconds: number;
|
|
68
|
+
watched_version: number;
|
|
69
|
+
last_watched_at: string | null;
|
|
70
|
+
}
|
|
71
|
+
interface CatalogResponse {
|
|
72
|
+
data: StoryListItem[];
|
|
73
|
+
meta: {
|
|
74
|
+
previews: Record<string, StoryPreview>;
|
|
75
|
+
popular_choices: Record<string, PopularChoice[]>;
|
|
76
|
+
creator_avatars: Record<string, string>;
|
|
77
|
+
coverboxes: Record<string, string | null>;
|
|
78
|
+
progress: Record<string, StoryProgress>;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
interface SceneChoice {
|
|
82
|
+
id: string;
|
|
83
|
+
label: string;
|
|
84
|
+
choice_type: string;
|
|
85
|
+
choice_icon: string | null;
|
|
86
|
+
choice_icon_media_id: string | null;
|
|
87
|
+
choice_icon_url: string | null;
|
|
88
|
+
reveal_mode: string;
|
|
89
|
+
start_time_seconds: number | null;
|
|
90
|
+
pause_for_choice: boolean;
|
|
91
|
+
end_time_seconds: number | null;
|
|
92
|
+
target_scene_id: string;
|
|
93
|
+
x: number;
|
|
94
|
+
y: number;
|
|
95
|
+
w: number;
|
|
96
|
+
h: number;
|
|
97
|
+
visibility_rules: VisibilityRules | null;
|
|
98
|
+
state_updates: StateUpdate[];
|
|
99
|
+
}
|
|
100
|
+
interface VisibilityRules {
|
|
101
|
+
mode: "all" | "any";
|
|
102
|
+
conditions: VisibilityCondition[];
|
|
103
|
+
}
|
|
104
|
+
interface VisibilityCondition {
|
|
105
|
+
variable?: string;
|
|
106
|
+
key?: string;
|
|
107
|
+
operator?: string;
|
|
108
|
+
value?: string;
|
|
109
|
+
}
|
|
110
|
+
interface StateUpdate {
|
|
111
|
+
variable?: string;
|
|
112
|
+
key?: string;
|
|
113
|
+
action?: string;
|
|
114
|
+
value?: string;
|
|
115
|
+
}
|
|
116
|
+
interface SceneNode {
|
|
117
|
+
type: string;
|
|
118
|
+
properties?: Record<string, unknown>;
|
|
119
|
+
children?: SceneNode[];
|
|
120
|
+
}
|
|
121
|
+
interface SceneMapEntry {
|
|
122
|
+
scene_id: string;
|
|
123
|
+
scene_title: string;
|
|
124
|
+
color: string | null;
|
|
125
|
+
is_title: boolean;
|
|
126
|
+
media_title: string | null;
|
|
127
|
+
media_type: string | null;
|
|
128
|
+
media_url: string | null;
|
|
129
|
+
stream_status: string | null;
|
|
130
|
+
choice_style: string;
|
|
131
|
+
choice_overlay_mode: string;
|
|
132
|
+
goto_scene_id: string | null;
|
|
133
|
+
choices: SceneChoice[];
|
|
134
|
+
nodes: SceneNode[];
|
|
135
|
+
}
|
|
136
|
+
interface TreeGraphNode {
|
|
137
|
+
id: string;
|
|
138
|
+
title: string;
|
|
139
|
+
is_title: boolean;
|
|
140
|
+
is_end: boolean;
|
|
141
|
+
level: number;
|
|
142
|
+
index: number;
|
|
143
|
+
x: number;
|
|
144
|
+
y: number;
|
|
145
|
+
color: string | null;
|
|
146
|
+
}
|
|
147
|
+
interface TreeGraphEdge {
|
|
148
|
+
id: string;
|
|
149
|
+
source: string;
|
|
150
|
+
target: string;
|
|
151
|
+
type: "choice" | "go_to_scene";
|
|
152
|
+
}
|
|
153
|
+
interface TreeGraph {
|
|
154
|
+
nodes: TreeGraphNode[];
|
|
155
|
+
edges: TreeGraphEdge[];
|
|
156
|
+
meta: {
|
|
157
|
+
root_id: string | null;
|
|
158
|
+
level_count: number;
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
interface WatchSnapshot {
|
|
162
|
+
scene_id: string | null;
|
|
163
|
+
state: Record<string, string>;
|
|
164
|
+
history: HistoryEntry[];
|
|
165
|
+
path: string[];
|
|
166
|
+
visited_scene_ids?: string[];
|
|
167
|
+
playback_seconds: number;
|
|
168
|
+
}
|
|
169
|
+
interface HistoryEntry {
|
|
170
|
+
choice_id: string;
|
|
171
|
+
scene_id: string;
|
|
172
|
+
target_scene_id: string | null;
|
|
173
|
+
at: string | null;
|
|
174
|
+
path_index: number | null;
|
|
175
|
+
}
|
|
176
|
+
interface SceneMapResponse {
|
|
177
|
+
story: {
|
|
178
|
+
id: string;
|
|
179
|
+
title: string;
|
|
180
|
+
description: string | null;
|
|
181
|
+
genre: string | null;
|
|
182
|
+
content_rating: ContentRating | null;
|
|
183
|
+
published_version: number;
|
|
184
|
+
watch_starts_count: number;
|
|
185
|
+
choice_clicks_count: number;
|
|
186
|
+
};
|
|
187
|
+
start_scene_id: string;
|
|
188
|
+
scene_map: Record<string, SceneMapEntry>;
|
|
189
|
+
tree_graph: TreeGraph;
|
|
190
|
+
initial_snapshot: WatchSnapshot;
|
|
191
|
+
initial_bookmark_code: string | null;
|
|
192
|
+
}
|
|
193
|
+
interface TrackEngagementRequest {
|
|
194
|
+
event: "play_start" | "choice_click";
|
|
195
|
+
choice_id?: string;
|
|
196
|
+
}
|
|
197
|
+
interface EngagementResponse {
|
|
198
|
+
watch_starts_count: number;
|
|
199
|
+
choice_clicks_count: number;
|
|
200
|
+
}
|
|
201
|
+
interface SaveBookmarkRequest {
|
|
202
|
+
snapshot: WatchSnapshot;
|
|
203
|
+
}
|
|
204
|
+
interface BookmarkResponse {
|
|
205
|
+
code: string;
|
|
206
|
+
snapshot: WatchSnapshot;
|
|
207
|
+
}
|
|
208
|
+
interface BookmarkListItem {
|
|
209
|
+
code: string;
|
|
210
|
+
snapshot: WatchSnapshot;
|
|
211
|
+
updated_at: string;
|
|
212
|
+
}
|
|
213
|
+
interface BookmarkListResponse {
|
|
214
|
+
bookmarks: BookmarkListItem[];
|
|
215
|
+
}
|
|
216
|
+
interface PaginatedLink {
|
|
217
|
+
url: string | null;
|
|
218
|
+
label: string;
|
|
219
|
+
active: boolean;
|
|
220
|
+
}
|
|
221
|
+
interface PaginatedResponse<T> {
|
|
222
|
+
data: T[];
|
|
223
|
+
current_page: number;
|
|
224
|
+
first_page_url: string;
|
|
225
|
+
from: number | null;
|
|
226
|
+
last_page: number;
|
|
227
|
+
last_page_url: string;
|
|
228
|
+
links: PaginatedLink[];
|
|
229
|
+
next_page_url: string | null;
|
|
230
|
+
path: string;
|
|
231
|
+
per_page: number;
|
|
232
|
+
prev_page_url: string | null;
|
|
233
|
+
to: number | null;
|
|
234
|
+
total: number;
|
|
235
|
+
}
|
|
236
|
+
interface CreateStoryRequest {
|
|
237
|
+
title: string;
|
|
238
|
+
description?: string | null;
|
|
239
|
+
genre?: string | null;
|
|
240
|
+
content_rating?: ContentRating | null;
|
|
241
|
+
}
|
|
242
|
+
type ContentRating = "G" | "PG" | "PG-13" | "R" | "NC-17";
|
|
243
|
+
interface ContentRatingDefinition {
|
|
244
|
+
id: ContentRating;
|
|
245
|
+
label: string;
|
|
246
|
+
description: string;
|
|
247
|
+
}
|
|
248
|
+
type RealmId = "cosmos" | "wilds";
|
|
249
|
+
/** Supported UI locales — matches PHP `chuzi_realms.supported_locales`. */
|
|
250
|
+
type LocaleId = "en" | "es" | "fr" | "de" | "pt";
|
|
251
|
+
interface RealmDefinition {
|
|
252
|
+
label: string;
|
|
253
|
+
short_label: string;
|
|
254
|
+
/** Canonical English lexicon (always present). */
|
|
255
|
+
lexicon: Record<string, string>;
|
|
256
|
+
/** Optional per-locale overrides; missing keys fall through to `lexicon`. */
|
|
257
|
+
locales?: Partial<Record<LocaleId, Record<string, string>>>;
|
|
258
|
+
}
|
|
259
|
+
interface RealmConfigResponse {
|
|
260
|
+
realms: Record<RealmId, RealmDefinition>;
|
|
261
|
+
fallback_lexicon: Record<string, string>;
|
|
262
|
+
fallback_locales?: Partial<Record<LocaleId, Record<string, string>>>;
|
|
263
|
+
intro: {
|
|
264
|
+
line1: string;
|
|
265
|
+
line2: string;
|
|
266
|
+
};
|
|
267
|
+
intro_locales?: Partial<Record<LocaleId, {
|
|
268
|
+
line1: string;
|
|
269
|
+
line2: string;
|
|
270
|
+
}>>;
|
|
271
|
+
profile: {
|
|
272
|
+
title: string;
|
|
273
|
+
current_prefix: string;
|
|
274
|
+
switch_prompt: string;
|
|
275
|
+
};
|
|
276
|
+
profile_locales?: Partial<Record<LocaleId, {
|
|
277
|
+
title: string;
|
|
278
|
+
current_prefix: string;
|
|
279
|
+
switch_prompt: string;
|
|
280
|
+
}>>;
|
|
281
|
+
allowed_realm_ids: RealmId[];
|
|
282
|
+
supported_locales: LocaleId[];
|
|
283
|
+
locale_labels?: Partial<Record<LocaleId, string>>;
|
|
284
|
+
}
|
|
285
|
+
interface UpdateLocaleRequest {
|
|
286
|
+
locale: LocaleId;
|
|
287
|
+
}
|
|
288
|
+
interface UpdateLocaleResponse {
|
|
289
|
+
locale: LocaleId;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export type { BookmarkListItem, BookmarkListResponse, BookmarkResponse, CatalogResponse, ContentRating, ContentRatingDefinition, CreateStoryRequest, EngagementResponse, HistoryEntry, LocaleId, LoginRequest, LoginResponse, PaginatedLink, PaginatedResponse, PopularChoice, RealmConfigResponse, RealmDefinition, RealmId, SaveBookmarkRequest, SceneChoice, SceneMapEntry, SceneMapResponse, SceneNode, StateUpdate, StoryListItem, StoryPreview, StoryProgress, TrackEngagementRequest, TreeGraph, TreeGraphEdge, TreeGraphNode, UpdateLocaleRequest, UpdateLocaleResponse, UpdateProfileRequest, UpdateProfileResponse, UpdateRealmRequest, UpdateRealmResponse, UserProfile, VisibilityCondition, VisibilityRules, WatchSnapshot };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { RealmThemeTokens } from '../themes/index.js';
|
|
4
|
+
import { RealmId, LocaleId, StoryListItem } from '../types/index.js';
|
|
5
|
+
import { PressableProps, StyleProp, ViewStyle } from 'react-native';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Realm-aware theme + lexicon context. Every chuzi-shared/ui primitive reads
|
|
9
|
+
* from this; consuming apps wrap their tree once at the top level. Switching
|
|
10
|
+
* realms or locales re-renders all consumers without prop drilling.
|
|
11
|
+
*/
|
|
12
|
+
interface RealmTheme {
|
|
13
|
+
realmId: RealmId | null;
|
|
14
|
+
locale: LocaleId | null;
|
|
15
|
+
tokens: RealmThemeTokens;
|
|
16
|
+
/** Realm + locale aware lexicon lookup. */
|
|
17
|
+
t: (key: string, fallback?: string) => string;
|
|
18
|
+
/** Full merged lexicon for the current realm + locale. */
|
|
19
|
+
lexicon: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
interface RealmThemeProviderProps {
|
|
22
|
+
realmId: RealmId | null;
|
|
23
|
+
locale?: LocaleId | null;
|
|
24
|
+
children: ReactNode;
|
|
25
|
+
}
|
|
26
|
+
declare function RealmThemeProvider({ realmId, locale, children, }: RealmThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
27
|
+
declare function useRealmTheme(): RealmTheme;
|
|
28
|
+
|
|
29
|
+
type ButtonVariant = "primary" | "ghost";
|
|
30
|
+
interface ButtonProps extends Omit<PressableProps, "style" | "children"> {
|
|
31
|
+
label: string;
|
|
32
|
+
variant?: ButtonVariant;
|
|
33
|
+
style?: StyleProp<ViewStyle>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Realm-themed button. Primitives come from react-native so the same
|
|
37
|
+
* component renders on web (via react-native-web) and native. Colors come
|
|
38
|
+
* from the active realm's theme tokens — primary fills with accent, ghost
|
|
39
|
+
* draws an accent outline.
|
|
40
|
+
*/
|
|
41
|
+
declare function Button({ label, variant, style, ...rest }: ButtonProps): react_jsx_runtime.JSX.Element;
|
|
42
|
+
|
|
43
|
+
interface FilmCardProps {
|
|
44
|
+
film: StoryListItem;
|
|
45
|
+
/** Tap/click handler. Without one, the card is a static block. */
|
|
46
|
+
onPress?: () => void;
|
|
47
|
+
style?: StyleProp<ViewStyle>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Realm-themed film card. Title falls back to the realm's "untitled" lexicon
|
|
51
|
+
* (Untitled Star System / Untitled Grove). Genre falls back to the realm's
|
|
52
|
+
* "unknown genre" string. Pressable when an onPress is provided; otherwise
|
|
53
|
+
* renders a non-interactive View — important for list contexts that want
|
|
54
|
+
* the press handled at the row level instead.
|
|
55
|
+
*/
|
|
56
|
+
declare function FilmCard({ film, onPress, style }: FilmCardProps): react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
type CreditRole = "viewer" | "creator";
|
|
59
|
+
interface CreditBadgeProps {
|
|
60
|
+
role: CreditRole;
|
|
61
|
+
value: number;
|
|
62
|
+
style?: StyleProp<ViewStyle>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Realm-themed credit badge — a bordered label showing a viewer or creator
|
|
66
|
+
* credit balance. The label text adapts to the active realm's lexicon and
|
|
67
|
+
* colors pull from the realm's theme tokens.
|
|
68
|
+
*/
|
|
69
|
+
declare function CreditBadge({ role, value, style }: CreditBadgeProps): react_jsx_runtime.JSX.Element;
|
|
70
|
+
|
|
71
|
+
export { Button, type ButtonProps, type ButtonVariant, CreditBadge, type CreditBadgeProps, type CreditRole, FilmCard, type FilmCardProps, type RealmTheme, RealmThemeProvider, type RealmThemeProviderProps, useRealmTheme };
|